diff --git a/dist/index.js b/dist/index.js index 674784b..93d9a7e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -2408,244 +2408,59 @@ exports.checkBypass = checkBypass; /***/ }), -/***/ 9904: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.FunctionsClient = void 0; -const helper_1 = __nccwpck_require__(618); -const types_1 = __nccwpck_require__(3136); -class FunctionsClient { - constructor(url, { headers = {}, customFetch, } = {}) { - this.url = url; - this.headers = headers; - this.fetch = (0, helper_1.resolveFetch)(customFetch); - } - /** - * Updates the authorization header - * @param token - the new jwt token sent in the authorisation header - */ - setAuth(token) { - this.headers.Authorization = `Bearer ${token}`; - } - /** - * Invokes a function - * @param functionName - The name of the Function to invoke. - * @param options - Options for invoking the Function. - */ - invoke(functionName, options = {}) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - try { - const { headers, method, body: functionArgs } = options; - let _headers = {}; - let body; - if (functionArgs && - ((headers && !Object.prototype.hasOwnProperty.call(headers, 'Content-Type')) || !headers)) { - if ((typeof Blob !== 'undefined' && functionArgs instanceof Blob) || - functionArgs instanceof ArrayBuffer) { - // will work for File as File inherits Blob - // also works for ArrayBuffer as it is the same underlying structure as a Blob - _headers['Content-Type'] = 'application/octet-stream'; - body = functionArgs; - } - else if (typeof functionArgs === 'string') { - // plain string - _headers['Content-Type'] = 'text/plain'; - body = functionArgs; - } - else if (typeof FormData !== 'undefined' && functionArgs instanceof FormData) { - // don't set content-type headers - // Request will automatically add the right boundary value - body = functionArgs; - } - else { - // default, assume this is JSON - _headers['Content-Type'] = 'application/json'; - body = JSON.stringify(functionArgs); - } - } - const response = yield this.fetch(`${this.url}/${functionName}`, { - method: method || 'POST', - // headers priority is (high to low): - // 1. invoke-level headers - // 2. client-level headers - // 3. default Content-Type header - headers: Object.assign(Object.assign(Object.assign({}, _headers), this.headers), headers), - body, - }).catch((fetchError) => { - throw new types_1.FunctionsFetchError(fetchError); - }); - const isRelayError = response.headers.get('x-relay-error'); - if (isRelayError && isRelayError === 'true') { - throw new types_1.FunctionsRelayError(response); - } - if (!response.ok) { - throw new types_1.FunctionsHttpError(response); - } - let responseType = ((_a = response.headers.get('Content-Type')) !== null && _a !== void 0 ? _a : 'text/plain').split(';')[0].trim(); - let data; - if (responseType === 'application/json') { - data = yield response.json(); - } - else if (responseType === 'application/octet-stream') { - data = yield response.blob(); - } - else if (responseType === 'multipart/form-data') { - data = yield response.formData(); - } - else { - // default to text - data = yield response.text(); - } - return { data, error: null }; - } - catch (error) { - return { data: null, error }; - } - }); - } -} -exports.FunctionsClient = FunctionsClient; -//# sourceMappingURL=FunctionsClient.js.map - -/***/ }), - -/***/ 618: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.resolveFetch = void 0; -const resolveFetch = (customFetch) => { - let _fetch; - if (customFetch) { - _fetch = customFetch; - } - else if (typeof fetch === 'undefined') { - _fetch = (...args) => Promise.resolve().then(() => __importStar(__nccwpck_require__(2668))).then(({ default: fetch }) => fetch(...args)); - } - else { - _fetch = fetch; - } - return (...args) => _fetch(...args); -}; -exports.resolveFetch = resolveFetch; -//# sourceMappingURL=helper.js.map - -/***/ }), - -/***/ 8519: +/***/ 9809: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.FunctionsRelayError = exports.FunctionsHttpError = exports.FunctionsFetchError = exports.FunctionsError = exports.FunctionsClient = void 0; -var FunctionsClient_1 = __nccwpck_require__(9904); -Object.defineProperty(exports, "FunctionsClient", ({ enumerable: true, get: function () { return FunctionsClient_1.FunctionsClient; } })); -var types_1 = __nccwpck_require__(3136); -Object.defineProperty(exports, "FunctionsError", ({ enumerable: true, get: function () { return types_1.FunctionsError; } })); -Object.defineProperty(exports, "FunctionsFetchError", ({ enumerable: true, get: function () { return types_1.FunctionsFetchError; } })); -Object.defineProperty(exports, "FunctionsHttpError", ({ enumerable: true, get: function () { return types_1.FunctionsHttpError; } })); -Object.defineProperty(exports, "FunctionsRelayError", ({ enumerable: true, get: function () { return types_1.FunctionsRelayError; } })); -//# sourceMappingURL=index.js.map +const tslib_1 = __nccwpck_require__(9808); +const GoTrueAdminApi_1 = tslib_1.__importDefault(__nccwpck_require__(6575)); +const AuthAdminApi = GoTrueAdminApi_1.default; +exports["default"] = AuthAdminApi; +//# sourceMappingURL=AuthAdminApi.js.map /***/ }), -/***/ 3136: -/***/ ((__unused_webpack_module, exports) => { +/***/ 4525: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.FunctionsHttpError = exports.FunctionsRelayError = exports.FunctionsFetchError = exports.FunctionsError = void 0; -class FunctionsError extends Error { - constructor(message, name = 'FunctionsError', context) { - super(message); - this.name = name; - this.context = context; - } -} -exports.FunctionsError = FunctionsError; -class FunctionsFetchError extends FunctionsError { - constructor(context) { - super('Failed to send a request to the Edge Function', 'FunctionsFetchError', context); - } -} -exports.FunctionsFetchError = FunctionsFetchError; -class FunctionsRelayError extends FunctionsError { - constructor(context) { - super('Relay Error invoking the Edge Function', 'FunctionsRelayError', context); - } -} -exports.FunctionsRelayError = FunctionsRelayError; -class FunctionsHttpError extends FunctionsError { - constructor(context) { - super('Edge Function returned a non-2xx status code', 'FunctionsHttpError', context); - } -} -exports.FunctionsHttpError = FunctionsHttpError; -//# sourceMappingURL=types.js.map +const tslib_1 = __nccwpck_require__(9808); +const GoTrueClient_1 = tslib_1.__importDefault(__nccwpck_require__(313)); +const AuthClient = GoTrueClient_1.default; +exports["default"] = AuthClient; +//# sourceMappingURL=AuthClient.js.map /***/ }), -/***/ 4599: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 6575: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -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; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -const fetch_1 = __nccwpck_require__(202); -const helpers_1 = __nccwpck_require__(2846); -const errors_1 = __nccwpck_require__(6723); +const tslib_1 = __nccwpck_require__(9808); +const fetch_1 = __nccwpck_require__(7072); +const helpers_1 = __nccwpck_require__(4044); +const types_1 = __nccwpck_require__(1852); +const errors_1 = __nccwpck_require__(9938); class GoTrueAdminApi { + /** + * Creates an admin API client that can be used to manage users and OAuth clients. + * + * @example + * ```ts + * import { GoTrueAdminApi } from '@supabase/auth-js' + * + * const admin = new GoTrueAdminApi({ + * url: 'https://xyzcompany.supabase.co/auth/v1', + * headers: { Authorization: `Bearer ${process.env.SUPABASE_SERVICE_ROLE_KEY}` }, + * }) + * ``` + */ constructor({ url = '', headers = {}, fetch, }) { this.url = url; this.headers = headers; @@ -2654,13 +2469,31 @@ class GoTrueAdminApi { listFactors: this._listFactors.bind(this), deleteFactor: this._deleteFactor.bind(this), }; + this.oauth = { + listClients: this._listOAuthClients.bind(this), + createClient: this._createOAuthClient.bind(this), + getClient: this._getOAuthClient.bind(this), + updateClient: this._updateOAuthClient.bind(this), + deleteClient: this._deleteOAuthClient.bind(this), + regenerateClientSecret: this._regenerateOAuthClientSecret.bind(this), + }; + this.customProviders = { + listProviders: this._listCustomProviders.bind(this), + createProvider: this._createCustomProvider.bind(this), + getProvider: this._getCustomProvider.bind(this), + updateProvider: this._updateCustomProvider.bind(this), + deleteProvider: this._deleteCustomProvider.bind(this), + }; } /** * Removes a logged-in session. * @param jwt A valid, logged-in JWT. * @param scope The logout sope. */ - async signOut(jwt, scope = 'global') { + async signOut(jwt, scope = types_1.SIGN_OUT_SCOPES[0]) { + if (types_1.SIGN_OUT_SCOPES.indexOf(scope) < 0) { + throw new Error(`@supabase/auth-js: Parameter scope must be one of ${types_1.SIGN_OUT_SCOPES.join(', ')}`); + } try { await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/logout?scope=${scope}`, { headers: this.headers, @@ -2706,7 +2539,7 @@ class GoTrueAdminApi { */ async generateLink(params) { try { - const { options } = params, rest = __rest(params, ["options"]); + const { options } = params, rest = tslib_1.__rest(params, ["options"]); const body = Object.assign(Object.assign({}, rest), options); if ('newEmail' in rest) { // replace newEmail with new_email in request body @@ -2802,6 +2635,7 @@ class GoTrueAdminApi { * This function should only be called on a server. Never expose your `service_role` key in the browser. */ async getUserById(uid) { + (0, helpers_1.validateUUID)(uid); try { return await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/admin/users/${uid}`, { headers: this.headers, @@ -2816,13 +2650,39 @@ class GoTrueAdminApi { } } /** - * Updates the user data. + * Updates the user data. Changes are applied directly without confirmation flows. * + * @param uid The user's unique identifier * @param attributes The data you want to update. * * This function should only be called on a server. Never expose your `service_role` key in the browser. + * + * @remarks + * **Important:** This is a server-side operation and does **not** trigger client-side + * `onAuthStateChange` listeners. The admin API has no connection to client state. + * + * To sync changes to the client after calling this method: + * 1. On the client, call `supabase.auth.refreshSession()` to fetch the updated user data + * 2. This will trigger the `TOKEN_REFRESHED` event and notify all listeners + * + * @example + * ```typescript + * // Server-side (Edge Function) + * const { data, error } = await supabase.auth.admin.updateUserById( + * userId, + * { user_metadata: { preferences: { theme: 'dark' } } } + * ) + * + * // Client-side (to sync the changes) + * const { data, error } = await supabase.auth.refreshSession() + * // onAuthStateChange listeners will now be notified with updated user + * ``` + * + * @see {@link GoTrueClient.refreshSession} for syncing admin changes to the client + * @see {@link GoTrueClient.updateUser} for client-side user updates (triggers listeners automatically) */ async updateUserById(uid, attributes) { + (0, helpers_1.validateUUID)(uid); try { return await (0, fetch_1._request)(this.fetch, 'PUT', `${this.url}/admin/users/${uid}`, { body: attributes, @@ -2841,12 +2701,13 @@ class GoTrueAdminApi { * Delete a user. Requires a `service_role` key. * * @param id The user id you want to remove. - * @param shouldSoftDelete If true, then the user will be soft-deleted from the auth schema. + * @param shouldSoftDelete If true, then the user will be soft-deleted from the auth schema. Soft deletion allows user identification from the hashed user ID but is not reversible. * Defaults to false for backward compatibility. * * This function should only be called on a server. Never expose your `service_role` key in the browser. */ async deleteUser(id, shouldSoftDelete = false) { + (0, helpers_1.validateUUID)(id); try { return await (0, fetch_1._request)(this.fetch, 'DELETE', `${this.url}/admin/users/${id}`, { headers: this.headers, @@ -2864,6 +2725,7 @@ class GoTrueAdminApi { } } async _listFactors(params) { + (0, helpers_1.validateUUID)(params.userId); try { const { data, error } = await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/admin/users/${params.userId}/factors`, { headers: this.headers, @@ -2881,6 +2743,8 @@ class GoTrueAdminApi { } } async _deleteFactor(params) { + (0, helpers_1.validateUUID)(params.userId); + (0, helpers_1.validateUUID)(params.id); try { const data = await (0, fetch_1._request)(this.fetch, 'DELETE', `${this.url}/admin/users/${params.userId}/factors/${params.id}`, { headers: this.headers, @@ -2894,30 +2758,306 @@ class GoTrueAdminApi { throw error; } } + /** + * Lists all OAuth clients with optional pagination. + * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. + * + * This function should only be called on a server. Never expose your `service_role` key in the browser. + */ + async _listOAuthClients(params) { + var _a, _b, _c, _d, _e, _f, _g; + try { + const pagination = { nextPage: null, lastPage: 0, total: 0 }; + const response = await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/admin/oauth/clients`, { + headers: this.headers, + noResolveJson: true, + query: { + page: (_b = (_a = params === null || params === void 0 ? void 0 : params.page) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : '', + per_page: (_d = (_c = params === null || params === void 0 ? void 0 : params.perPage) === null || _c === void 0 ? void 0 : _c.toString()) !== null && _d !== void 0 ? _d : '', + }, + xform: fetch_1._noResolveJsonResponse, + }); + if (response.error) + throw response.error; + const clients = await response.json(); + const total = (_e = response.headers.get('x-total-count')) !== null && _e !== void 0 ? _e : 0; + const links = (_g = (_f = response.headers.get('link')) === null || _f === void 0 ? void 0 : _f.split(',')) !== null && _g !== void 0 ? _g : []; + if (links.length > 0) { + links.forEach((link) => { + const page = parseInt(link.split(';')[0].split('=')[1].substring(0, 1)); + const rel = JSON.parse(link.split(';')[1].split('=')[1]); + pagination[`${rel}Page`] = page; + }); + pagination.total = parseInt(total); + } + return { data: Object.assign(Object.assign({}, clients), pagination), error: null }; + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: { clients: [] }, error }; + } + throw error; + } + } + /** + * Creates a new OAuth client. + * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. + * + * This function should only be called on a server. Never expose your `service_role` key in the browser. + */ + async _createOAuthClient(params) { + try { + return await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/admin/oauth/clients`, { + body: params, + headers: this.headers, + xform: (client) => { + return { data: client, error: null }; + }, + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: null, error }; + } + throw error; + } + } + /** + * Gets details of a specific OAuth client. + * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. + * + * This function should only be called on a server. Never expose your `service_role` key in the browser. + */ + async _getOAuthClient(clientId) { + try { + return await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/admin/oauth/clients/${clientId}`, { + headers: this.headers, + xform: (client) => { + return { data: client, error: null }; + }, + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: null, error }; + } + throw error; + } + } + /** + * Updates an existing OAuth client. + * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. + * + * This function should only be called on a server. Never expose your `service_role` key in the browser. + */ + async _updateOAuthClient(clientId, params) { + try { + return await (0, fetch_1._request)(this.fetch, 'PUT', `${this.url}/admin/oauth/clients/${clientId}`, { + body: params, + headers: this.headers, + xform: (client) => { + return { data: client, error: null }; + }, + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: null, error }; + } + throw error; + } + } + /** + * Deletes an OAuth client. + * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. + * + * This function should only be called on a server. Never expose your `service_role` key in the browser. + */ + async _deleteOAuthClient(clientId) { + try { + await (0, fetch_1._request)(this.fetch, 'DELETE', `${this.url}/admin/oauth/clients/${clientId}`, { + headers: this.headers, + noResolveJson: true, + }); + return { data: null, error: null }; + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: null, error }; + } + throw error; + } + } + /** + * Regenerates the secret for an OAuth client. + * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. + * + * This function should only be called on a server. Never expose your `service_role` key in the browser. + */ + async _regenerateOAuthClientSecret(clientId) { + try { + return await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/admin/oauth/clients/${clientId}/regenerate_secret`, { + headers: this.headers, + xform: (client) => { + return { data: client, error: null }; + }, + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: null, error }; + } + throw error; + } + } + /** + * Lists all custom providers with optional type filter. + * + * This function should only be called on a server. Never expose your `service_role` key in the browser. + */ + async _listCustomProviders(params) { + try { + const query = {}; + if (params === null || params === void 0 ? void 0 : params.type) { + query.type = params.type; + } + return await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/admin/custom-providers`, { + headers: this.headers, + query, + xform: (data) => { + var _a; + return { data: { providers: (_a = data === null || data === void 0 ? void 0 : data.providers) !== null && _a !== void 0 ? _a : [] }, error: null }; + }, + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: { providers: [] }, error }; + } + throw error; + } + } + /** + * Creates a new custom OIDC/OAuth provider. + * + * For OIDC providers, the server fetches and validates the OpenID Connect discovery document + * from the issuer's well-known endpoint (or the provided `discovery_url`) at creation time. + * This may return a validation error (`error_code: "validation_failed"`) if the discovery + * document is unreachable, not valid JSON, missing required fields, or if the issuer + * in the document does not match the expected issuer. + * + * This function should only be called on a server. Never expose your `service_role` key in the browser. + */ + async _createCustomProvider(params) { + try { + return await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/admin/custom-providers`, { + body: params, + headers: this.headers, + xform: (provider) => { + return { data: provider, error: null }; + }, + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: null, error }; + } + throw error; + } + } + /** + * Gets details of a specific custom provider by identifier. + * + * This function should only be called on a server. Never expose your `service_role` key in the browser. + */ + async _getCustomProvider(identifier) { + try { + return await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/admin/custom-providers/${identifier}`, { + headers: this.headers, + xform: (provider) => { + return { data: provider, error: null }; + }, + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: null, error }; + } + throw error; + } + } + /** + * Updates an existing custom provider. + * + * When `issuer` or `discovery_url` is changed on an OIDC provider, the server re-fetches and + * validates the discovery document before persisting. This may return a validation error + * (`error_code: "validation_failed"`) if the discovery document is unreachable, invalid, or + * the issuer does not match. + * + * This function should only be called on a server. Never expose your `service_role` key in the browser. + */ + async _updateCustomProvider(identifier, params) { + try { + return await (0, fetch_1._request)(this.fetch, 'PUT', `${this.url}/admin/custom-providers/${identifier}`, { + body: params, + headers: this.headers, + xform: (provider) => { + return { data: provider, error: null }; + }, + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: null, error }; + } + throw error; + } + } + /** + * Deletes a custom provider. + * + * This function should only be called on a server. Never expose your `service_role` key in the browser. + */ + async _deleteCustomProvider(identifier) { + try { + await (0, fetch_1._request)(this.fetch, 'DELETE', `${this.url}/admin/custom-providers/${identifier}`, { + headers: this.headers, + noResolveJson: true, + }); + return { data: null, error: null }; + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: null, error }; + } + throw error; + } + } } exports["default"] = GoTrueAdminApi; //# sourceMappingURL=GoTrueAdminApi.js.map /***/ }), -/***/ 7139: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 313: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -const GoTrueAdminApi_1 = __importDefault(__nccwpck_require__(4599)); -const constants_1 = __nccwpck_require__(2496); -const errors_1 = __nccwpck_require__(6723); -const fetch_1 = __nccwpck_require__(202); -const helpers_1 = __nccwpck_require__(2846); -const local_storage_1 = __nccwpck_require__(9766); -const polyfills_1 = __nccwpck_require__(5568); -const version_1 = __nccwpck_require__(5910); -const locks_1 = __nccwpck_require__(7000); +const tslib_1 = __nccwpck_require__(9808); +const GoTrueAdminApi_1 = tslib_1.__importDefault(__nccwpck_require__(6575)); +const constants_1 = __nccwpck_require__(518); +const errors_1 = __nccwpck_require__(9938); +const fetch_1 = __nccwpck_require__(7072); +const helpers_1 = __nccwpck_require__(4044); +const local_storage_1 = __nccwpck_require__(1479); +const locks_1 = __nccwpck_require__(163); +const polyfills_1 = __nccwpck_require__(1897); +const version_1 = __nccwpck_require__(6677); +const base64url_1 = __nccwpck_require__(3649); +const ethereum_1 = __nccwpck_require__(9031); +const webauthn_1 = __nccwpck_require__(9451); (0, polyfills_1.polyfillGlobalThis)(); // Make "globalThis" available const DEFAULT_OPTIONS = { url: constants_1.GOTRUE_URL, @@ -2928,34 +3068,77 @@ const DEFAULT_OPTIONS = { headers: constants_1.DEFAULT_HEADERS, flowType: 'implicit', debug: false, + hasCustomAuthorizationHeader: false, + throwOnError: false, + lockAcquireTimeout: 5000, // 5 seconds + skipAutoInitialize: false, }; -/** Current session will be checked for refresh at this interval. */ -const AUTO_REFRESH_TICK_DURATION = 30 * 1000; -/** - * A token refresh will be attempted this many ticks before the current session expires. */ -const AUTO_REFRESH_TICK_THRESHOLD = 3; async function lockNoOp(name, acquireTimeout, fn) { return await fn(); } +/** + * Caches JWKS values for all clients created in the same environment. This is + * especially useful for shared-memory execution environments such as Vercel's + * Fluid Compute, AWS Lambda or Supabase's Edge Functions. Regardless of how + * many clients are created, if they share the same storage key they will use + * the same JWKS cache, significantly speeding up getClaims() with asymmetric + * JWTs. + */ +const GLOBAL_JWKS = {}; class GoTrueClient { + /** + * The JWKS used for verifying asymmetric JWTs + */ + get jwks() { + var _a, _b; + return (_b = (_a = GLOBAL_JWKS[this.storageKey]) === null || _a === void 0 ? void 0 : _a.jwks) !== null && _b !== void 0 ? _b : { keys: [] }; + } + set jwks(value) { + GLOBAL_JWKS[this.storageKey] = Object.assign(Object.assign({}, GLOBAL_JWKS[this.storageKey]), { jwks: value }); + } + get jwks_cached_at() { + var _a, _b; + return (_b = (_a = GLOBAL_JWKS[this.storageKey]) === null || _a === void 0 ? void 0 : _a.cachedAt) !== null && _b !== void 0 ? _b : Number.MIN_SAFE_INTEGER; + } + set jwks_cached_at(value) { + GLOBAL_JWKS[this.storageKey] = Object.assign(Object.assign({}, GLOBAL_JWKS[this.storageKey]), { cachedAt: value }); + } /** * Create a new client for use in the browser. + * + * @example + * ```ts + * import { GoTrueClient } from '@supabase/auth-js' + * + * const auth = new GoTrueClient({ + * url: 'https://xyzcompany.supabase.co/auth/v1', + * headers: { apikey: 'public-anon-key' }, + * storageKey: 'supabase-auth', + * }) + * ``` */ constructor(options) { - var _a; + var _a, _b, _c; + /** + * @experimental + */ + this.userStorage = null; this.memoryStorage = null; this.stateChangeEmitters = new Map(); this.autoRefreshTicker = null; + this.autoRefreshTickTimeout = null; this.visibilityChangedCallback = null; this.refreshingDeferred = null; /** * Keeps track of the async client initialization. * When null or not yet resolved the auth state is `unknown` - * Once resolved the the auth state is known and it's save to call any further client methods. + * Once resolved the auth state is known and it's safe to call any further client methods. * Keep extra care to never reject or throw uncaught errors */ this.initializePromise = null; this.detectSessionInUrl = true; + this.hasCustomAuthorizationHeader = false; + this.suppressGetSessionWarning = false; this.lockAcquired = false; this.pendingInLock = []; /** @@ -2963,18 +3146,22 @@ class GoTrueClient { */ this.broadcastChannel = null; this.logger = console.log; - this.instanceID = GoTrueClient.nextInstanceID; - GoTrueClient.nextInstanceID += 1; - if (this.instanceID > 0 && (0, helpers_1.isBrowser)()) { - console.warn('Multiple GoTrueClient instances detected in the same browser context. It is not an error, but this should be avoided as it may produce undefined behavior when used concurrently under the same storage key.'); - } const settings = Object.assign(Object.assign({}, DEFAULT_OPTIONS), options); + this.storageKey = settings.storageKey; + this.instanceID = (_a = GoTrueClient.nextInstanceID[this.storageKey]) !== null && _a !== void 0 ? _a : 0; + GoTrueClient.nextInstanceID[this.storageKey] = this.instanceID + 1; this.logDebugMessages = !!settings.debug; if (typeof settings.debug === 'function') { this.logger = settings.debug; } + if (this.instanceID > 0 && (0, helpers_1.isBrowser)()) { + const message = `${this._logPrefix()} Multiple GoTrueClient instances detected in the same browser context. It is not an error, but this should be avoided as it may produce undefined behavior when used concurrently under the same storage key.`; + console.warn(message); + if (this.logDebugMessages) { + console.trace(message); + } + } this.persistSession = settings.persistSession; - this.storageKey = settings.storageKey; this.autoRefreshToken = settings.autoRefreshToken; this.admin = new GoTrueAdminApi_1.default({ url: settings.url, @@ -2987,6 +3174,22 @@ class GoTrueClient { this.lock = settings.lock || lockNoOp; this.detectSessionInUrl = settings.detectSessionInUrl; this.flowType = settings.flowType; + this.hasCustomAuthorizationHeader = settings.hasCustomAuthorizationHeader; + this.throwOnError = settings.throwOnError; + this.lockAcquireTimeout = settings.lockAcquireTimeout; + if (settings.lock) { + this.lock = settings.lock; + } + else if (this.persistSession && (0, helpers_1.isBrowser)() && ((_b = globalThis === null || globalThis === void 0 ? void 0 : globalThis.navigator) === null || _b === void 0 ? void 0 : _b.locks)) { + this.lock = locks_1.navigatorLock; + } + else { + this.lock = lockNoOp; + } + if (!this.jwks) { + this.jwks = { keys: [] }; + this.jwks_cached_at = Number.MIN_SAFE_INTEGER; + } this.mfa = { verify: this._verify.bind(this), enroll: this._enroll.bind(this), @@ -2995,6 +3198,14 @@ class GoTrueClient { listFactors: this._listFactors.bind(this), challengeAndVerify: this._challengeAndVerify.bind(this), getAuthenticatorAssuranceLevel: this._getAuthenticatorAssuranceLevel.bind(this), + webauthn: new webauthn_1.WebAuthnApi(this), + }; + this.oauth = { + getAuthorizationDetails: this._getAuthorizationDetails.bind(this), + approveAuthorization: this._approveAuthorization.bind(this), + denyAuthorization: this._denyAuthorization.bind(this), + listGrants: this._listOAuthGrants.bind(this), + revokeGrant: this._revokeOAuthGrant.bind(this), }; if (this.persistSession) { if (settings.storage) { @@ -3002,13 +3213,16 @@ class GoTrueClient { } else { if ((0, helpers_1.supportsLocalStorage)()) { - this.storage = local_storage_1.localStorageAdapter; + this.storage = globalThis.localStorage; } else { this.memoryStorage = {}; this.storage = (0, local_storage_1.memoryLocalStorageAdapter)(this.memoryStorage); } } + if (settings.userStorage) { + this.userStorage = settings.userStorage; + } } else { this.memoryStorage = {}; @@ -3021,16 +3235,49 @@ class GoTrueClient { catch (e) { console.error('Failed to create a new BroadcastChannel, multi-tab state changes will not be available', e); } - (_a = this.broadcastChannel) === null || _a === void 0 ? void 0 : _a.addEventListener('message', async (event) => { + (_c = this.broadcastChannel) === null || _c === void 0 ? void 0 : _c.addEventListener('message', async (event) => { this._debug('received broadcast notification from other tab or client', event); - await this._notifyAllSubscribers(event.data.event, event.data.session, false); // broadcast = false so we don't get an endless loop of messages + try { + await this._notifyAllSubscribers(event.data.event, event.data.session, false); // broadcast = false so we don't get an endless loop of messages + } + catch (error) { + this._debug('#broadcastChannel', 'error', error); + } + }); + } + // Only auto-initialize if not explicitly disabled. Skipped in SSR contexts + // where initialization timing must be controlled. All public methods have + // lazy initialization, so the client remains fully functional. + if (!settings.skipAutoInitialize) { + this.initialize().catch((error) => { + this._debug('#initialize()', 'error', error); }); } - this.initialize(); + } + /** + * Returns whether error throwing mode is enabled for this client. + */ + isThrowOnErrorEnabled() { + return this.throwOnError; + } + /** + * Centralizes return handling with optional error throwing. When `throwOnError` is enabled + * and the provided result contains a non-nullish error, the error is thrown instead of + * being returned. This ensures consistent behavior across all public API methods. + */ + _returnResult(result) { + if (this.throwOnError && result && result.error) { + throw result.error; + } + return result; + } + _logPrefix() { + return ('GoTrueClient@' + + `${this.storageKey}:${this.instanceID} (${version_1.version}) ${new Date().toISOString()}`); } _debug(...args) { if (this.logDebugMessages) { - this.logger(`GoTrueClient@${this.instanceID} (${version_1.version}) ${new Date().toISOString()}`, ...args); + this.logger(this._logPrefix(), ...args); } return this; } @@ -3044,7 +3291,7 @@ class GoTrueClient { return await this.initializePromise; } this.initializePromise = (async () => { - return await this._acquireLock(-1, async () => { + return await this._acquireLock(this.lockAcquireTimeout, async () => { return await this._initialize(); }); })(); @@ -3057,16 +3304,39 @@ class GoTrueClient { * the whole lifetime of the client */ async _initialize() { + var _a; try { - const isPKCEFlow = (0, helpers_1.isBrowser)() ? await this._isPKCEFlow() : false; - this._debug('#_initialize()', 'begin', 'is PKCE flow', isPKCEFlow); - if (isPKCEFlow || (this.detectSessionInUrl && this._isImplicitGrantFlow())) { - const { data, error } = await this._getSessionFromURL(isPKCEFlow); + let params = {}; + let callbackUrlType = 'none'; + if ((0, helpers_1.isBrowser)()) { + params = (0, helpers_1.parseParametersFromURL)(window.location.href); + if (this._isImplicitGrantCallback(params)) { + callbackUrlType = 'implicit'; + } + else if (await this._isPKCECallback(params)) { + callbackUrlType = 'pkce'; + } + } + /** + * Attempt to get the session from the URL only if these conditions are fulfilled + * + * Note: If the URL isn't one of the callback url types (implicit or pkce), + * then there could be an existing session so we don't want to prematurely remove it + */ + if ((0, helpers_1.isBrowser)() && this.detectSessionInUrl && callbackUrlType !== 'none') { + const { data, error } = await this._getSessionFromURL(params, callbackUrlType); if (error) { this._debug('#_initialize()', 'error detecting session from URL', error); - // failed login attempt via url, - // remove old session as in verifyOtp, signUp and signInWith* - await this._removeSession(); + if ((0, errors_1.isAuthImplicitGrantRedirectError)(error)) { + const errorCode = (_a = error.details) === null || _a === void 0 ? void 0 : _a.code; + if (errorCode === 'identity_already_exists' || + errorCode === 'identity_not_found' || + errorCode === 'single_identity_not_deletable') { + return { error }; + } + } + // Don't remove existing session on URL login failure. + // A failed attempt (e.g. reused magic link) shouldn't invalidate a valid session. return { error }; } const { session, redirectType } = data; @@ -3088,17 +3358,52 @@ class GoTrueClient { } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { error }; + return this._returnResult({ error }); } - return { + return this._returnResult({ error: new errors_1.AuthUnknownError('Unexpected error during initialization', error), - }; + }); } finally { await this._handleVisibilityChange(); this._debug('#_initialize()', 'end'); } } + /** + * Creates a new anonymous user. + * + * @returns A session where the is_anonymous claim in the access token JWT set to true + */ + async signInAnonymously(credentials) { + var _a, _b, _c; + try { + const res = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/signup`, { + headers: this.headers, + body: { + data: (_b = (_a = credentials === null || credentials === void 0 ? void 0 : credentials.options) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : {}, + gotrue_meta_security: { captcha_token: (_c = credentials === null || credentials === void 0 ? void 0 : credentials.options) === null || _c === void 0 ? void 0 : _c.captchaToken }, + }, + xform: fetch_1._sessionResponse, + }); + const { data, error } = res; + if (error || !data) { + return this._returnResult({ data: { user: null, session: null }, error: error }); + } + const session = data.session; + const user = data.user; + if (data.session) { + await this._saveSession(data.session); + await this._notifyAllSubscribers('SIGNED_IN', session); + } + return this._returnResult({ data: { user, session }, error: null }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: { user: null, session: null }, error }); + } + throw error; + } + } /** * Creates a new user. * @@ -3112,17 +3417,14 @@ class GoTrueClient { async signUp(credentials) { var _a, _b, _c; try { - await this._removeSession(); let res; if ('email' in credentials) { const { email, password, options } = credentials; let codeChallenge = null; let codeChallengeMethod = null; if (this.flowType === 'pkce') { - const codeVerifier = (0, helpers_1.generatePKCEVerifier)(); - await (0, helpers_1.setItemAsync)(this.storage, `${this.storageKey}-code-verifier`, codeVerifier); - codeChallenge = await (0, helpers_1.generatePKCEChallenge)(codeVerifier); - codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256'; + ; + [codeChallenge, codeChallengeMethod] = await (0, helpers_1.getCodeChallengeAndMethod)(this.storage, this.storageKey); } res = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/signup`, { headers: this.headers, @@ -3157,7 +3459,8 @@ class GoTrueClient { } const { data, error } = res; if (error || !data) { - return { data: { user: null, session: null }, error: error }; + await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`); + return this._returnResult({ data: { user: null, session: null }, error: error }); } const session = data.session; const user = data.user; @@ -3165,11 +3468,12 @@ class GoTrueClient { await this._saveSession(data.session); await this._notifyAllSubscribers('SIGNED_IN', session); } - return { data: { user, session }, error: null }; + return this._returnResult({ data: { user, session }, error: null }); } catch (error) { + await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`); if ((0, errors_1.isAuthError)(error)) { - return { data: { user: null, session: null }, error }; + return this._returnResult({ data: { user: null, session: null }, error }); } throw error; } @@ -3184,7 +3488,6 @@ class GoTrueClient { */ async signInWithPassword(credentials) { try { - await this._removeSession(); let res; if ('email' in credentials) { const { email, password, options } = credentials; @@ -3195,7 +3498,7 @@ class GoTrueClient { password, gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken }, }, - xform: fetch_1._sessionResponse, + xform: fetch_1._sessionResponsePassword, }); } else if ('phone' in credentials) { @@ -3207,7 +3510,7 @@ class GoTrueClient { password, gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken }, }, - xform: fetch_1._sessionResponse, + xform: fetch_1._sessionResponsePassword, }); } else { @@ -3215,20 +3518,24 @@ class GoTrueClient { } const { data, error } = res; if (error) { - return { data: { user: null, session: null }, error }; + return this._returnResult({ data: { user: null, session: null }, error }); } else if (!data || !data.session || !data.user) { - return { data: { user: null, session: null }, error: new errors_1.AuthInvalidTokenResponseError() }; + const invalidTokenError = new errors_1.AuthInvalidTokenResponseError(); + return this._returnResult({ data: { user: null, session: null }, error: invalidTokenError }); } if (data.session) { await this._saveSession(data.session); await this._notifyAllSubscribers('SIGNED_IN', data.session); } - return { data: { user: data.user, session: data.session }, error }; + return this._returnResult({ + data: Object.assign({ user: data.user, session: data.session }, (data.weak_password ? { weakPassword: data.weak_password } : null)), + error, + }); } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { data: { user: null, session: null }, error }; + return this._returnResult({ data: { user: null, session: null }, error }); } throw error; } @@ -3239,7 +3546,6 @@ class GoTrueClient { */ async signInWithOAuth(credentials) { var _a, _b, _c, _d; - await this._removeSession(); return await this._handleProviderSignIn(credentials.provider, { redirectTo: (_a = credentials.options) === null || _a === void 0 ? void 0 : _a.redirectTo, scopes: (_b = credentials.options) === null || _b === void 0 ? void 0 : _b.scopes, @@ -3252,44 +3558,322 @@ class GoTrueClient { */ async exchangeCodeForSession(authCode) { await this.initializePromise; - return this._acquireLock(-1, async () => { + return this._acquireLock(this.lockAcquireTimeout, async () => { return this._exchangeCodeForSession(authCode); }); } - async _exchangeCodeForSession(authCode) { - const codeVerifier = await (0, helpers_1.getItemAsync)(this.storage, `${this.storageKey}-code-verifier`); - const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/token?grant_type=pkce`, { - headers: this.headers, - body: { - auth_code: authCode, - code_verifier: codeVerifier, - }, - xform: fetch_1._sessionResponse, - }); - await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`); - if (error) { - return { data: { user: null, session: null }, error }; - } - else if (!data || !data.session || !data.user) { - return { data: { user: null, session: null }, error: new errors_1.AuthInvalidTokenResponseError() }; - } - if (data.session) { - await this._saveSession(data.session); - await this._notifyAllSubscribers('SIGNED_IN', data.session); - } - return { data, error }; - } /** - * Allows signing in with an OIDC ID token. The authentication provider used - * should be enabled and configured. + * Signs in a user by verifying a message signed by the user's private key. + * Supports Ethereum (via Sign-In-With-Ethereum) & Solana (Sign-In-With-Solana) standards, + * both of which derive from the EIP-4361 standard + * With slight variation on Solana's side. + * @reference https://eips.ethereum.org/EIPS/eip-4361 */ - async signInWithIdToken(credentials) { - await this._removeSession(); - try { - const { options, provider, token, access_token, nonce } = credentials; - const res = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/token?grant_type=id_token`, { - headers: this.headers, - body: { + async signInWithWeb3(credentials) { + const { chain } = credentials; + switch (chain) { + case 'ethereum': + return await this.signInWithEthereum(credentials); + case 'solana': + return await this.signInWithSolana(credentials); + default: + throw new Error(`@supabase/auth-js: Unsupported chain "${chain}"`); + } + } + async signInWithEthereum(credentials) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l; + // TODO: flatten type + let message; + let signature; + if ('message' in credentials) { + message = credentials.message; + signature = credentials.signature; + } + else { + const { chain, wallet, statement, options } = credentials; + let resolvedWallet; + if (!(0, helpers_1.isBrowser)()) { + if (typeof wallet !== 'object' || !(options === null || options === void 0 ? void 0 : options.url)) { + throw new Error('@supabase/auth-js: Both wallet and url must be specified in non-browser environments.'); + } + resolvedWallet = wallet; + } + else if (typeof wallet === 'object') { + resolvedWallet = wallet; + } + else { + const windowAny = window; + if ('ethereum' in windowAny && + typeof windowAny.ethereum === 'object' && + 'request' in windowAny.ethereum && + typeof windowAny.ethereum.request === 'function') { + resolvedWallet = windowAny.ethereum; + } + else { + throw new Error(`@supabase/auth-js: No compatible Ethereum wallet interface on the window object (window.ethereum) detected. Make sure the user already has a wallet installed and connected for this app. Prefer passing the wallet interface object directly to signInWithWeb3({ chain: 'ethereum', wallet: resolvedUserWallet }) instead.`); + } + } + const url = new URL((_a = options === null || options === void 0 ? void 0 : options.url) !== null && _a !== void 0 ? _a : window.location.href); + const accounts = await resolvedWallet + .request({ + method: 'eth_requestAccounts', + }) + .then((accs) => accs) + .catch(() => { + throw new Error(`@supabase/auth-js: Wallet method eth_requestAccounts is missing or invalid`); + }); + if (!accounts || accounts.length === 0) { + throw new Error(`@supabase/auth-js: No accounts available. Please ensure the wallet is connected.`); + } + const address = (0, ethereum_1.getAddress)(accounts[0]); + let chainId = (_b = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _b === void 0 ? void 0 : _b.chainId; + if (!chainId) { + const chainIdHex = await resolvedWallet.request({ + method: 'eth_chainId', + }); + chainId = (0, ethereum_1.fromHex)(chainIdHex); + } + const siweMessage = { + domain: url.host, + address: address, + statement: statement, + uri: url.href, + version: '1', + chainId: chainId, + nonce: (_c = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _c === void 0 ? void 0 : _c.nonce, + issuedAt: (_e = (_d = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _d === void 0 ? void 0 : _d.issuedAt) !== null && _e !== void 0 ? _e : new Date(), + expirationTime: (_f = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _f === void 0 ? void 0 : _f.expirationTime, + notBefore: (_g = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _g === void 0 ? void 0 : _g.notBefore, + requestId: (_h = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _h === void 0 ? void 0 : _h.requestId, + resources: (_j = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _j === void 0 ? void 0 : _j.resources, + }; + message = (0, ethereum_1.createSiweMessage)(siweMessage); + // Sign message + signature = (await resolvedWallet.request({ + method: 'personal_sign', + params: [(0, ethereum_1.toHex)(message), address], + })); + } + try { + const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/token?grant_type=web3`, { + headers: this.headers, + body: Object.assign({ chain: 'ethereum', message, + signature }, (((_k = credentials.options) === null || _k === void 0 ? void 0 : _k.captchaToken) + ? { gotrue_meta_security: { captcha_token: (_l = credentials.options) === null || _l === void 0 ? void 0 : _l.captchaToken } } + : null)), + xform: fetch_1._sessionResponse, + }); + if (error) { + throw error; + } + if (!data || !data.session || !data.user) { + const invalidTokenError = new errors_1.AuthInvalidTokenResponseError(); + return this._returnResult({ data: { user: null, session: null }, error: invalidTokenError }); + } + if (data.session) { + await this._saveSession(data.session); + await this._notifyAllSubscribers('SIGNED_IN', data.session); + } + return this._returnResult({ data: Object.assign({}, data), error }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: { user: null, session: null }, error }); + } + throw error; + } + } + async signInWithSolana(credentials) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; + let message; + let signature; + if ('message' in credentials) { + message = credentials.message; + signature = credentials.signature; + } + else { + const { chain, wallet, statement, options } = credentials; + let resolvedWallet; + if (!(0, helpers_1.isBrowser)()) { + if (typeof wallet !== 'object' || !(options === null || options === void 0 ? void 0 : options.url)) { + throw new Error('@supabase/auth-js: Both wallet and url must be specified in non-browser environments.'); + } + resolvedWallet = wallet; + } + else if (typeof wallet === 'object') { + resolvedWallet = wallet; + } + else { + const windowAny = window; + if ('solana' in windowAny && + typeof windowAny.solana === 'object' && + (('signIn' in windowAny.solana && typeof windowAny.solana.signIn === 'function') || + ('signMessage' in windowAny.solana && + typeof windowAny.solana.signMessage === 'function'))) { + resolvedWallet = windowAny.solana; + } + else { + throw new Error(`@supabase/auth-js: No compatible Solana wallet interface on the window object (window.solana) detected. Make sure the user already has a wallet installed and connected for this app. Prefer passing the wallet interface object directly to signInWithWeb3({ chain: 'solana', wallet: resolvedUserWallet }) instead.`); + } + } + const url = new URL((_a = options === null || options === void 0 ? void 0 : options.url) !== null && _a !== void 0 ? _a : window.location.href); + if ('signIn' in resolvedWallet && resolvedWallet.signIn) { + const output = await resolvedWallet.signIn(Object.assign(Object.assign(Object.assign({ issuedAt: new Date().toISOString() }, options === null || options === void 0 ? void 0 : options.signInWithSolana), { + // non-overridable properties + version: '1', domain: url.host, uri: url.href }), (statement ? { statement } : null))); + let outputToProcess; + if (Array.isArray(output) && output[0] && typeof output[0] === 'object') { + outputToProcess = output[0]; + } + else if (output && + typeof output === 'object' && + 'signedMessage' in output && + 'signature' in output) { + outputToProcess = output; + } + else { + throw new Error('@supabase/auth-js: Wallet method signIn() returned unrecognized value'); + } + if ('signedMessage' in outputToProcess && + 'signature' in outputToProcess && + (typeof outputToProcess.signedMessage === 'string' || + outputToProcess.signedMessage instanceof Uint8Array) && + outputToProcess.signature instanceof Uint8Array) { + message = + typeof outputToProcess.signedMessage === 'string' + ? outputToProcess.signedMessage + : new TextDecoder().decode(outputToProcess.signedMessage); + signature = outputToProcess.signature; + } + else { + throw new Error('@supabase/auth-js: Wallet method signIn() API returned object without signedMessage and signature fields'); + } + } + else { + if (!('signMessage' in resolvedWallet) || + typeof resolvedWallet.signMessage !== 'function' || + !('publicKey' in resolvedWallet) || + typeof resolvedWallet !== 'object' || + !resolvedWallet.publicKey || + !('toBase58' in resolvedWallet.publicKey) || + typeof resolvedWallet.publicKey.toBase58 !== 'function') { + throw new Error('@supabase/auth-js: Wallet does not have a compatible signMessage() and publicKey.toBase58() API'); + } + message = [ + `${url.host} wants you to sign in with your Solana account:`, + resolvedWallet.publicKey.toBase58(), + ...(statement ? ['', statement, ''] : ['']), + 'Version: 1', + `URI: ${url.href}`, + `Issued At: ${(_c = (_b = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _b === void 0 ? void 0 : _b.issuedAt) !== null && _c !== void 0 ? _c : new Date().toISOString()}`, + ...(((_d = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _d === void 0 ? void 0 : _d.notBefore) + ? [`Not Before: ${options.signInWithSolana.notBefore}`] + : []), + ...(((_e = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _e === void 0 ? void 0 : _e.expirationTime) + ? [`Expiration Time: ${options.signInWithSolana.expirationTime}`] + : []), + ...(((_f = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _f === void 0 ? void 0 : _f.chainId) + ? [`Chain ID: ${options.signInWithSolana.chainId}`] + : []), + ...(((_g = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _g === void 0 ? void 0 : _g.nonce) ? [`Nonce: ${options.signInWithSolana.nonce}`] : []), + ...(((_h = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _h === void 0 ? void 0 : _h.requestId) + ? [`Request ID: ${options.signInWithSolana.requestId}`] + : []), + ...(((_k = (_j = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _j === void 0 ? void 0 : _j.resources) === null || _k === void 0 ? void 0 : _k.length) + ? [ + 'Resources', + ...options.signInWithSolana.resources.map((resource) => `- ${resource}`), + ] + : []), + ].join('\n'); + const maybeSignature = await resolvedWallet.signMessage(new TextEncoder().encode(message), 'utf8'); + if (!maybeSignature || !(maybeSignature instanceof Uint8Array)) { + throw new Error('@supabase/auth-js: Wallet signMessage() API returned an recognized value'); + } + signature = maybeSignature; + } + } + try { + const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/token?grant_type=web3`, { + headers: this.headers, + body: Object.assign({ chain: 'solana', message, signature: (0, base64url_1.bytesToBase64URL)(signature) }, (((_l = credentials.options) === null || _l === void 0 ? void 0 : _l.captchaToken) + ? { gotrue_meta_security: { captcha_token: (_m = credentials.options) === null || _m === void 0 ? void 0 : _m.captchaToken } } + : null)), + xform: fetch_1._sessionResponse, + }); + if (error) { + throw error; + } + if (!data || !data.session || !data.user) { + const invalidTokenError = new errors_1.AuthInvalidTokenResponseError(); + return this._returnResult({ data: { user: null, session: null }, error: invalidTokenError }); + } + if (data.session) { + await this._saveSession(data.session); + await this._notifyAllSubscribers('SIGNED_IN', data.session); + } + return this._returnResult({ data: Object.assign({}, data), error }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: { user: null, session: null }, error }); + } + throw error; + } + } + async _exchangeCodeForSession(authCode) { + const storageItem = await (0, helpers_1.getItemAsync)(this.storage, `${this.storageKey}-code-verifier`); + const [codeVerifier, redirectType] = (storageItem !== null && storageItem !== void 0 ? storageItem : '').split('/'); + try { + if (!codeVerifier && this.flowType === 'pkce') { + throw new errors_1.AuthPKCECodeVerifierMissingError(); + } + const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/token?grant_type=pkce`, { + headers: this.headers, + body: { + auth_code: authCode, + code_verifier: codeVerifier, + }, + xform: fetch_1._sessionResponse, + }); + await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`); + if (error) { + throw error; + } + if (!data || !data.session || !data.user) { + const invalidTokenError = new errors_1.AuthInvalidTokenResponseError(); + return this._returnResult({ + data: { user: null, session: null, redirectType: null }, + error: invalidTokenError, + }); + } + if (data.session) { + await this._saveSession(data.session); + await this._notifyAllSubscribers('SIGNED_IN', data.session); + } + return this._returnResult({ data: Object.assign(Object.assign({}, data), { redirectType: redirectType !== null && redirectType !== void 0 ? redirectType : null }), error }); + } + catch (error) { + await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`); + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ + data: { user: null, session: null, redirectType: null }, + error, + }); + } + throw error; + } + } + /** + * Allows signing in with an OIDC ID token. The authentication provider used + * should be enabled and configured. + */ + async signInWithIdToken(credentials) { + try { + const { options, provider, token, access_token, nonce } = credentials; + const res = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/token?grant_type=id_token`, { + headers: this.headers, + body: { provider, id_token: token, access_token, @@ -3300,23 +3884,21 @@ class GoTrueClient { }); const { data, error } = res; if (error) { - return { data: { user: null, session: null }, error }; + return this._returnResult({ data: { user: null, session: null }, error }); } else if (!data || !data.session || !data.user) { - return { - data: { user: null, session: null }, - error: new errors_1.AuthInvalidTokenResponseError(), - }; + const invalidTokenError = new errors_1.AuthInvalidTokenResponseError(); + return this._returnResult({ data: { user: null, session: null }, error: invalidTokenError }); } if (data.session) { await this._saveSession(data.session); await this._notifyAllSubscribers('SIGNED_IN', data.session); } - return { data, error }; + return this._returnResult({ data, error }); } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { data: { user: null, session: null }, error }; + return this._returnResult({ data: { user: null, session: null }, error }); } throw error; } @@ -3341,16 +3923,13 @@ class GoTrueClient { async signInWithOtp(credentials) { var _a, _b, _c, _d, _e; try { - await this._removeSession(); if ('email' in credentials) { const { email, options } = credentials; let codeChallenge = null; let codeChallengeMethod = null; if (this.flowType === 'pkce') { - const codeVerifier = (0, helpers_1.generatePKCEVerifier)(); - await (0, helpers_1.setItemAsync)(this.storage, `${this.storageKey}-code-verifier`, codeVerifier); - codeChallenge = await (0, helpers_1.generatePKCEChallenge)(codeVerifier); - codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256'; + ; + [codeChallenge, codeChallengeMethod] = await (0, helpers_1.getCodeChallengeAndMethod)(this.storage, this.storageKey); } const { error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/otp`, { headers: this.headers, @@ -3364,7 +3943,7 @@ class GoTrueClient { }, redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo, }); - return { data: { user: null, session: null }, error }; + return this._returnResult({ data: { user: null, session: null }, error }); } if ('phone' in credentials) { const { phone, options } = credentials; @@ -3378,13 +3957,17 @@ class GoTrueClient { channel: (_e = options === null || options === void 0 ? void 0 : options.channel) !== null && _e !== void 0 ? _e : 'sms', }, }); - return { data: { user: null, session: null, messageId: data === null || data === void 0 ? void 0 : data.message_id }, error }; + return this._returnResult({ + data: { user: null, session: null, messageId: data === null || data === void 0 ? void 0 : data.message_id }, + error, + }); } throw new errors_1.AuthInvalidCredentialsError('You must provide either an email or phone number.'); } catch (error) { + await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`); if ((0, errors_1.isAuthError)(error)) { - return { data: { user: null, session: null }, error }; + return this._returnResult({ data: { user: null, session: null }, error }); } throw error; } @@ -3395,10 +3978,6 @@ class GoTrueClient { async verifyOtp(params) { var _a, _b; try { - if (params.type !== 'email_change' && params.type !== 'phone_change') { - // we don't want to remove the authenticated session if the user is performing an email_change or phone_change verification - await this._removeSession(); - } let redirectTo = undefined; let captchaToken = undefined; if ('options' in params) { @@ -3415,19 +3994,20 @@ class GoTrueClient { throw error; } if (!data) { - throw new Error('An error occurred on token verification.'); + const tokenVerificationError = new Error('An error occurred on token verification.'); + throw tokenVerificationError; } const session = data.session; const user = data.user; if (session === null || session === void 0 ? void 0 : session.access_token) { await this._saveSession(session); - await this._notifyAllSubscribers('SIGNED_IN', session); + await this._notifyAllSubscribers(params.type == 'recovery' ? 'PASSWORD_RECOVERY' : 'SIGNED_IN', session); } - return { data: { user, session }, error: null }; + return this._returnResult({ data: { user, session }, error: null }); } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { data: { user: null, session: null }, error }; + return this._returnResult({ data: { user: null, session: null }, error }); } throw error; } @@ -3447,28 +4027,31 @@ class GoTrueClient { * organization's SSO Identity Provider UUID directly instead. */ async signInWithSSO(params) { - var _a, _b, _c; + var _a, _b, _c, _d, _e; try { - await this._removeSession(); let codeChallenge = null; let codeChallengeMethod = null; if (this.flowType === 'pkce') { - const codeVerifier = (0, helpers_1.generatePKCEVerifier)(); - await (0, helpers_1.setItemAsync)(this.storage, `${this.storageKey}-code-verifier`, codeVerifier); - codeChallenge = await (0, helpers_1.generatePKCEChallenge)(codeVerifier); - codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256'; + ; + [codeChallenge, codeChallengeMethod] = await (0, helpers_1.getCodeChallengeAndMethod)(this.storage, this.storageKey); } - return await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/sso`, { + const result = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/sso`, { body: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, ('providerId' in params ? { provider_id: params.providerId } : null)), ('domain' in params ? { domain: params.domain } : null)), { redirect_to: (_b = (_a = params.options) === null || _a === void 0 ? void 0 : _a.redirectTo) !== null && _b !== void 0 ? _b : undefined }), (((_c = params === null || params === void 0 ? void 0 : params.options) === null || _c === void 0 ? void 0 : _c.captchaToken) ? { gotrue_meta_security: { captcha_token: params.options.captchaToken } } : null)), { skip_http_redirect: true, code_challenge: codeChallenge, code_challenge_method: codeChallengeMethod }), headers: this.headers, xform: fetch_1._ssoResponse, }); + // Automatically redirect in browser unless skipBrowserRedirect is true + if (((_d = result.data) === null || _d === void 0 ? void 0 : _d.url) && (0, helpers_1.isBrowser)() && !((_e = params.options) === null || _e === void 0 ? void 0 : _e.skipBrowserRedirect)) { + window.location.assign(result.data.url); + } + return this._returnResult(result); } catch (error) { + await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`); if ((0, errors_1.isAuthError)(error)) { - return { data: null, error }; + return this._returnResult({ data: null, error }); } throw error; } @@ -3479,7 +4062,7 @@ class GoTrueClient { */ async reauthenticate() { await this.initializePromise; - return await this._acquireLock(-1, async () => { + return await this._acquireLock(this.lockAcquireTimeout, async () => { return await this._reauthenticate(); }); } @@ -3495,12 +4078,12 @@ class GoTrueClient { headers: this.headers, jwt: session.access_token, }); - return { data: { user: null, session: null }, error }; + return this._returnResult({ data: { user: null, session: null }, error }); }); } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { data: { user: null, session: null }, error }; + return this._returnResult({ data: { user: null, session: null }, error }); } throw error; } @@ -3510,9 +4093,6 @@ class GoTrueClient { */ async resend(credentials) { try { - if (credentials.type != 'email_change' && credentials.type != 'phone_change') { - await this._removeSession(); - } const endpoint = `${this.url}/resend`; if ('email' in credentials) { const { email, type, options } = credentials; @@ -3525,7 +4105,7 @@ class GoTrueClient { }, redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo, }); - return { data: { user: null, session: null }, error }; + return this._returnResult({ data: { user: null, session: null }, error }); } else if ('phone' in credentials) { const { phone, type, options } = credentials; @@ -3537,28 +4117,39 @@ class GoTrueClient { gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken }, }, }); - return { data: { user: null, session: null, messageId: data === null || data === void 0 ? void 0 : data.message_id }, error }; + return this._returnResult({ + data: { user: null, session: null, messageId: data === null || data === void 0 ? void 0 : data.message_id }, + error, + }); } throw new errors_1.AuthInvalidCredentialsError('You must provide either an email or phone number and a type'); } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { data: { user: null, session: null }, error }; + return this._returnResult({ data: { user: null, session: null }, error }); } throw error; } } /** * Returns the session, refreshing it if necessary. + * * The session returned can be null if the session is not detected which can happen in the event a user is not signed-in or has logged out. + * + * **IMPORTANT:** This method loads values directly from the storage attached + * to the client. If that storage is based on request cookies for example, + * the values in it may not be authentic and therefore it's strongly advised + * against using this method and its results in such circumstances. A warning + * will be emitted if this is detected. Use {@link #getUser()} instead. */ async getSession() { await this.initializePromise; - return this._acquireLock(-1, async () => { + const result = await this._acquireLock(this.lockAcquireTimeout, async () => { return this._useSession(async (result) => { return result; }); }); + return result; } /** * Acquires a global lock based on the storage key. @@ -3659,35 +4250,68 @@ class GoTrueClient { if (!currentSession) { return { data: { session: null }, error: null }; } + // A session is considered expired before the access token _actually_ + // expires. When the autoRefreshToken option is off (or when the tab is + // in the background), very eager users of getSession() -- like + // realtime-js -- might send a valid JWT which will expire by the time it + // reaches the server. const hasExpired = currentSession.expires_at - ? currentSession.expires_at <= Date.now() / 1000 + ? currentSession.expires_at * 1000 - Date.now() < constants_1.EXPIRY_MARGIN_MS : false; this._debug('#__loadSession()', `session has${hasExpired ? '' : ' not'} expired`, 'expires_at', currentSession.expires_at); if (!hasExpired) { + if (this.userStorage) { + const maybeUser = (await (0, helpers_1.getItemAsync)(this.userStorage, this.storageKey + '-user')); + if (maybeUser === null || maybeUser === void 0 ? void 0 : maybeUser.user) { + currentSession.user = maybeUser.user; + } + else { + currentSession.user = (0, helpers_1.userNotAvailableProxy)(); + } + } + // Wrap the user object with a warning proxy on the server + // This warns when properties of the user are accessed, not when session.user itself is accessed + if (this.storage.isServer && + currentSession.user && + !currentSession.user.__isUserNotAvailableProxy) { + const suppressWarningRef = { value: this.suppressGetSessionWarning }; + currentSession.user = (0, helpers_1.insecureUserWarningProxy)(currentSession.user, suppressWarningRef); + // Update the client-level suppression flag when the proxy suppresses the warning + if (suppressWarningRef.value) { + this.suppressGetSessionWarning = true; + } + } return { data: { session: currentSession }, error: null }; } - const { session, error } = await this._callRefreshToken(currentSession.refresh_token); + const { data: session, error } = await this._callRefreshToken(currentSession.refresh_token); if (error) { - return { data: { session: null }, error }; + return this._returnResult({ data: { session: null }, error }); } - return { data: { session }, error: null }; + return this._returnResult({ data: { session }, error: null }); } finally { this._debug('#__loadSession()', 'end'); } } /** - * Gets the current user details if there is an existing session. - * @param jwt Takes in an optional access token jwt. If no jwt is provided, getUser() will attempt to get the jwt from the current session. + * Gets the current user details if there is an existing session. This method + * performs a network request to the Supabase Auth server, so the returned + * value is authentic and can be used to base authorization rules on. + * + * @param jwt Takes in an optional access token JWT. If no JWT is provided, the JWT from the current session is used. */ async getUser(jwt) { if (jwt) { return await this._getUser(jwt); } await this.initializePromise; - return this._acquireLock(-1, async () => { + const result = await this._acquireLock(this.lockAcquireTimeout, async () => { return await this._getUser(); }); + if (result.data.user) { + this.suppressGetSessionWarning = true; + } + return result; } async _getUser(jwt) { try { @@ -3699,21 +4323,31 @@ class GoTrueClient { }); } return await this._useSession(async (result) => { - var _a, _b; + var _a, _b, _c; const { data, error } = result; if (error) { throw error; } + // returns an error if there is no access_token or custom authorization header + if (!((_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token) && !this.hasCustomAuthorizationHeader) { + return { data: { user: null }, error: new errors_1.AuthSessionMissingError() }; + } return await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/user`, { headers: this.headers, - jwt: (_b = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token) !== null && _b !== void 0 ? _b : undefined, + jwt: (_c = (_b = data.session) === null || _b === void 0 ? void 0 : _b.access_token) !== null && _c !== void 0 ? _c : undefined, xform: fetch_1._userResponse, }); }); } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { data: { user: null }, error }; + if ((0, errors_1.isAuthSessionMissingError)(error)) { + // JWT contains a `session_id` which does not correspond to an active + // session in the database, indicating the user is signed out. + await this._removeSession(); + await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`); + } + return this._returnResult({ data: { user: null }, error }); } throw error; } @@ -3723,7 +4357,7 @@ class GoTrueClient { */ async updateUser(attributes, options = {}) { await this.initializePromise; - return await this._acquireLock(-1, async () => { + return await this._acquireLock(this.lockAcquireTimeout, async () => { return await this._updateUser(attributes, options); }); } @@ -3741,10 +4375,8 @@ class GoTrueClient { let codeChallenge = null; let codeChallengeMethod = null; if (this.flowType === 'pkce' && attributes.email != null) { - const codeVerifier = (0, helpers_1.generatePKCEVerifier)(); - await (0, helpers_1.setItemAsync)(this.storage, `${this.storageKey}-code-verifier`, codeVerifier); - codeChallenge = await (0, helpers_1.generatePKCEChallenge)(codeVerifier); - codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256'; + ; + [codeChallenge, codeChallengeMethod] = await (0, helpers_1.getCodeChallengeAndMethod)(this.storage, this.storageKey); } const { data, error: userError } = await (0, fetch_1._request)(this.fetch, 'PUT', `${this.url}/user`, { headers: this.headers, @@ -3753,27 +4385,23 @@ class GoTrueClient { jwt: session.access_token, xform: fetch_1._userResponse, }); - if (userError) + if (userError) { throw userError; + } session.user = data.user; await this._saveSession(session); await this._notifyAllSubscribers('USER_UPDATED', session); - return { data: { user: session.user }, error: null }; + return this._returnResult({ data: { user: session.user }, error: null }); }); } catch (error) { + await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`); if ((0, errors_1.isAuthError)(error)) { - return { data: { user: null }, error }; + return this._returnResult({ data: { user: null }, error }); } throw error; } } - /** - * Decodes a JWT (without performing any validation). - */ - _decodeJWT(jwt) { - return (0, helpers_1.decodeJWTPayload)(jwt); - } /** * Sets the session data from the current session. If the current session is expired, setSession will take care of refreshing it to obtain a new session. * If the refresh token or access token in the current session is invalid, an error will be thrown. @@ -3781,7 +4409,7 @@ class GoTrueClient { */ async setSession(currentSession) { await this.initializePromise; - return await this._acquireLock(-1, async () => { + return await this._acquireLock(this.lockAcquireTimeout, async () => { return await this._setSession(currentSession); }); } @@ -3794,15 +4422,15 @@ class GoTrueClient { let expiresAt = timeNow; let hasExpired = true; let session = null; - const payload = (0, helpers_1.decodeJWTPayload)(currentSession.access_token); + const { payload } = (0, helpers_1.decodeJWT)(currentSession.access_token); if (payload.exp) { expiresAt = payload.exp; hasExpired = expiresAt <= timeNow; } if (hasExpired) { - const { session: refreshedSession, error } = await this._callRefreshToken(currentSession.refresh_token); + const { data: refreshedSession, error } = await this._callRefreshToken(currentSession.refresh_token); if (error) { - return { data: { user: null, session: null }, error: error }; + return this._returnResult({ data: { user: null, session: null }, error: error }); } if (!refreshedSession) { return { data: { user: null, session: null }, error: null }; @@ -3812,7 +4440,7 @@ class GoTrueClient { else { const { data, error } = await this._getUser(currentSession.access_token); if (error) { - throw error; + return this._returnResult({ data: { user: null, session: null }, error }); } session = { access_token: currentSession.access_token, @@ -3825,11 +4453,11 @@ class GoTrueClient { await this._saveSession(session); await this._notifyAllSubscribers('SIGNED_IN', session); } - return { data: { user: session.user, session }, error: null }; + return this._returnResult({ data: { user: session.user, session }, error: null }); } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { data: { session: null, user: null }, error }; + return this._returnResult({ data: { session: null, user: null }, error }); } throw error; } @@ -3842,7 +4470,7 @@ class GoTrueClient { */ async refreshSession(currentSession) { await this.initializePromise; - return await this._acquireLock(-1, async () => { + return await this._acquireLock(this.lockAcquireTimeout, async () => { return await this._refreshSession(currentSession); }); } @@ -3860,19 +4488,19 @@ class GoTrueClient { if (!(currentSession === null || currentSession === void 0 ? void 0 : currentSession.refresh_token)) { throw new errors_1.AuthSessionMissingError(); } - const { session, error } = await this._callRefreshToken(currentSession.refresh_token); + const { data: session, error } = await this._callRefreshToken(currentSession.refresh_token); if (error) { - return { data: { user: null, session: null }, error: error }; + return this._returnResult({ data: { user: null, session: null }, error: error }); } if (!session) { - return { data: { user: null, session: null }, error: null }; + return this._returnResult({ data: { user: null, session: null }, error: null }); } - return { data: { user: session.user, session }, error: null }; + return this._returnResult({ data: { user: session.user, session }, error: null }); }); } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { data: { user: null, session: null }, error }; + return this._returnResult({ data: { user: null, session: null }, error }); } throw error; } @@ -3880,18 +4508,37 @@ class GoTrueClient { /** * Gets the session data from a URL string */ - async _getSessionFromURL(isPKCEFlow) { + async _getSessionFromURL(params, callbackUrlType) { try { if (!(0, helpers_1.isBrowser)()) throw new errors_1.AuthImplicitGrantRedirectError('No browser detected.'); - if (this.flowType === 'implicit' && !this._isImplicitGrantFlow()) { - throw new errors_1.AuthImplicitGrantRedirectError('Not a valid implicit grant flow url.'); + // If there's an error in the URL, it doesn't matter what flow it is, we just return the error. + if (params.error || params.error_description || params.error_code) { + // The error class returned implies that the redirect is from an implicit grant flow + // but it could also be from a redirect error from a PKCE flow. + throw new errors_1.AuthImplicitGrantRedirectError(params.error_description || 'Error in URL with unspecified error_description', { + error: params.error || 'unspecified_error', + code: params.error_code || 'unspecified_code', + }); } - else if (this.flowType == 'pkce' && !isPKCEFlow) { - throw new errors_1.AuthPKCEGrantCodeExchangeError('Not a valid PKCE flow url.'); + // Checks for mismatches between the flowType initialised in the client and the URL parameters + switch (callbackUrlType) { + case 'implicit': + if (this.flowType === 'pkce') { + throw new errors_1.AuthPKCEGrantCodeExchangeError('Not a valid PKCE flow url.'); + } + break; + case 'pkce': + if (this.flowType === 'implicit') { + throw new errors_1.AuthImplicitGrantRedirectError('Not a valid implicit grant flow url.'); + } + break; + default: + // there's no mismatch so we continue } - const params = (0, helpers_1.parseParametersFromURL)(window.location.href); - if (isPKCEFlow) { + // Since this is a redirect for PKCE, we attempt to retrieve the code from the URL for the code exchange + if (callbackUrlType === 'pkce') { + this._debug('#_initialize()', 'begin', 'is PKCE flow', true); if (!params.code) throw new errors_1.AuthPKCEGrantCodeExchangeError('No code detected.'); const { data, error } = await this._exchangeCodeForSession(params.code); @@ -3902,12 +4549,6 @@ class GoTrueClient { window.history.replaceState(window.history.state, '', url.toString()); return { data: { session: data.session, redirectType: null }, error: null }; } - if (params.error || params.error_description || params.error_code) { - throw new errors_1.AuthImplicitGrantRedirectError(params.error_description || 'Error in URL with unspecified error_description', { - error: params.error || 'unspecified_error', - code: params.error_code || 'unspecified_code', - }); - } const { provider_token, provider_refresh_token, access_token, refresh_token, expires_in, expires_at, token_type, } = params; if (!access_token || !expires_in || !refresh_token || !token_type) { throw new errors_1.AuthImplicitGrantRedirectError('No session defined in URL'); @@ -3919,7 +4560,7 @@ class GoTrueClient { expiresAt = parseInt(expires_at); } const actuallyExpiresIn = expiresAt - timeNow; - if (actuallyExpiresIn * 1000 <= AUTO_REFRESH_TICK_DURATION) { + if (actuallyExpiresIn * 1000 <= constants_1.AUTO_REFRESH_TICK_DURATION_MS) { console.warn(`@supabase/gotrue-js: Session as retrieved from URL expires in ${actuallyExpiresIn}s, should have been closer to ${expiresIn}s`); } const issuedAt = expiresAt - expiresIn; @@ -3927,7 +4568,7 @@ class GoTrueClient { console.warn('@supabase/gotrue-js: Session as retrieved from URL was issued over 120s ago, URL could be stale', issuedAt, expiresAt, timeNow); } else if (timeNow - issuedAt < 0) { - console.warn('@supabase/gotrue-js: Session as retrieved from URL was issued in the future? Check the device clok for skew', issuedAt, expiresAt, timeNow); + console.warn('@supabase/gotrue-js: Session as retrieved from URL was issued in the future? Check the device clock for skew', issuedAt, expiresAt, timeNow); } const { data, error } = await this._getUser(access_token); if (error) @@ -3939,48 +4580,52 @@ class GoTrueClient { expires_in: expiresIn, expires_at: expiresAt, refresh_token, - token_type, + token_type: token_type, user: data.user, }; // Remove tokens from URL window.location.hash = ''; this._debug('#_getSessionFromURL()', 'clearing window.location.hash'); - return { data: { session, redirectType: params.type }, error: null }; + return this._returnResult({ data: { session, redirectType: params.type }, error: null }); } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { data: { session: null, redirectType: null }, error }; + return this._returnResult({ data: { session: null, redirectType: null }, error }); } throw error; } } /** * Checks if the current URL contains parameters given by an implicit oauth grant flow (https://www.rfc-editor.org/rfc/rfc6749.html#section-4.2) + * + * If `detectSessionInUrl` is a function, it will be called with the URL and params to determine + * if the URL should be processed as a Supabase auth callback. This allows users to exclude + * URLs from other OAuth providers (e.g., Facebook Login) that also return access_token in the fragment. */ - _isImplicitGrantFlow() { - const params = (0, helpers_1.parseParametersFromURL)(window.location.href); - return !!((0, helpers_1.isBrowser)() && (params.access_token || params.error_description)); + _isImplicitGrantCallback(params) { + if (typeof this.detectSessionInUrl === 'function') { + return this.detectSessionInUrl(new URL(window.location.href), params); + } + return Boolean(params.access_token || params.error_description); } /** * Checks if the current URL and backing storage contain parameters given by a PKCE flow */ - async _isPKCEFlow() { - const params = (0, helpers_1.parseParametersFromURL)(window.location.href); + async _isPKCECallback(params) { const currentStorageContent = await (0, helpers_1.getItemAsync)(this.storage, `${this.storageKey}-code-verifier`); return !!(params.code && currentStorageContent); } /** - * Inside a browser context, `signOut()` will remove the logged in user from the browser session - * and log them out - removing all items from localstorage and then trigger a `"SIGNED_OUT"` event. + * Inside a browser context, `signOut()` will remove the logged in user from the browser session and log them out - removing all items from localstorage and then trigger a `"SIGNED_OUT"` event. * * For server-side management, you can revoke all refresh tokens for a user by passing a user's JWT through to `auth.api.signOut(JWT: string)`. * There is no way to revoke a user's access token jwt until it expires. It is recommended to set a shorter expiry on the jwt for this reason. * - * If using others scope, no `SIGNED_OUT` event is fired! + * If using `others` scope, no `SIGNED_OUT` event is fired! */ async signOut(options = { scope: 'global' }) { await this.initializePromise; - return await this._acquireLock(-1, async () => { + return await this._acquireLock(this.lockAcquireTimeout, async () => { return await this._signOut(options); }); } @@ -3988,8 +4633,8 @@ class GoTrueClient { return await this._useSession(async (result) => { var _a; const { data, error: sessionError } = result; - if (sessionError) { - return { error: sessionError }; + if (sessionError && !(0, errors_1.isAuthSessionMissingError)(sessionError)) { + return this._returnResult({ error: sessionError }); } const accessToken = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token; if (accessToken) { @@ -3997,25 +4642,22 @@ class GoTrueClient { if (error) { // ignore 404s since user might not exist anymore // ignore 401s since an invalid or expired JWT should sign out the current session - if (!((0, errors_1.isAuthApiError)(error) && (error.status === 404 || error.status === 401))) { - return { error }; + if (!(((0, errors_1.isAuthApiError)(error) && + (error.status === 404 || error.status === 401 || error.status === 403)) || + (0, errors_1.isAuthSessionMissingError)(error))) { + return this._returnResult({ error }); } } } if (scope !== 'others') { await this._removeSession(); await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`); - await this._notifyAllSubscribers('SIGNED_OUT', null); } - return { error: null }; + return this._returnResult({ error: null }); }); } - /** - * Receive a notification every time an auth event happens. - * @param callback A callback function to be invoked when an auth event happens. - */ onAuthStateChange(callback) { - const id = (0, helpers_1.uuid)(); + const id = (0, helpers_1.generateCallbackId)(); const subscription = { id, callback, @@ -4028,7 +4670,7 @@ class GoTrueClient { this.stateChangeEmitters.set(id, subscription); (async () => { await this.initializePromise; - await this._acquireLock(-1, async () => { + await this._acquireLock(this.lockAcquireTimeout, async () => { this._emitInitialSession(id); }); })(); @@ -4052,8 +4694,8 @@ class GoTrueClient { }); } /** - * Sends a password reset request to an email address. - * This method supports the PKCE flow. + * Sends a password reset request to an email address. This method supports the PKCE flow. + * * @param email The email address of the user. * @param options.redirectTo The URL to send the user to after they click the password reset link. * @param options.captchaToken Verification token received when the user completes the captcha on the site. @@ -4062,10 +4704,9 @@ class GoTrueClient { let codeChallenge = null; let codeChallengeMethod = null; if (this.flowType === 'pkce') { - const codeVerifier = (0, helpers_1.generatePKCEVerifier)(); - await (0, helpers_1.setItemAsync)(this.storage, `${this.storageKey}-code-verifier`, codeVerifier); - codeChallenge = await (0, helpers_1.generatePKCEChallenge)(codeVerifier); - codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256'; + ; + [codeChallenge, codeChallengeMethod] = await (0, helpers_1.getCodeChallengeAndMethod)(this.storage, this.storageKey, true // isPasswordRecovery + ); } try { return await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/recover`, { @@ -4080,8 +4721,139 @@ class GoTrueClient { }); } catch (error) { + await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`); if ((0, errors_1.isAuthError)(error)) { - return { data: null, error }; + return this._returnResult({ data: null, error }); + } + throw error; + } + } + /** + * Gets all the identities linked to a user. + */ + async getUserIdentities() { + var _a; + try { + const { data, error } = await this.getUser(); + if (error) + throw error; + return this._returnResult({ data: { identities: (_a = data.user.identities) !== null && _a !== void 0 ? _a : [] }, error: null }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: null, error }); + } + throw error; + } + } + async linkIdentity(credentials) { + if ('token' in credentials) { + return this.linkIdentityIdToken(credentials); + } + return this.linkIdentityOAuth(credentials); + } + async linkIdentityOAuth(credentials) { + var _a; + try { + const { data, error } = await this._useSession(async (result) => { + var _a, _b, _c, _d, _e; + const { data, error } = result; + if (error) + throw error; + const url = await this._getUrlForProvider(`${this.url}/user/identities/authorize`, credentials.provider, { + redirectTo: (_a = credentials.options) === null || _a === void 0 ? void 0 : _a.redirectTo, + scopes: (_b = credentials.options) === null || _b === void 0 ? void 0 : _b.scopes, + queryParams: (_c = credentials.options) === null || _c === void 0 ? void 0 : _c.queryParams, + skipBrowserRedirect: true, + }); + return await (0, fetch_1._request)(this.fetch, 'GET', url, { + headers: this.headers, + jwt: (_e = (_d = data.session) === null || _d === void 0 ? void 0 : _d.access_token) !== null && _e !== void 0 ? _e : undefined, + }); + }); + if (error) + throw error; + if ((0, helpers_1.isBrowser)() && !((_a = credentials.options) === null || _a === void 0 ? void 0 : _a.skipBrowserRedirect)) { + window.location.assign(data === null || data === void 0 ? void 0 : data.url); + } + return this._returnResult({ + data: { provider: credentials.provider, url: data === null || data === void 0 ? void 0 : data.url }, + error: null, + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: { provider: credentials.provider, url: null }, error }); + } + throw error; + } + } + async linkIdentityIdToken(credentials) { + return await this._useSession(async (result) => { + var _a; + try { + const { error: sessionError, data: { session }, } = result; + if (sessionError) + throw sessionError; + const { options, provider, token, access_token, nonce } = credentials; + const res = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/token?grant_type=id_token`, { + headers: this.headers, + jwt: (_a = session === null || session === void 0 ? void 0 : session.access_token) !== null && _a !== void 0 ? _a : undefined, + body: { + provider, + id_token: token, + access_token, + nonce, + link_identity: true, + gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken }, + }, + xform: fetch_1._sessionResponse, + }); + const { data, error } = res; + if (error) { + return this._returnResult({ data: { user: null, session: null }, error }); + } + else if (!data || !data.session || !data.user) { + return this._returnResult({ + data: { user: null, session: null }, + error: new errors_1.AuthInvalidTokenResponseError(), + }); + } + if (data.session) { + await this._saveSession(data.session); + await this._notifyAllSubscribers('USER_UPDATED', data.session); + } + return this._returnResult({ data, error }); + } + catch (error) { + await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`); + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: { user: null, session: null }, error }); + } + throw error; + } + }); + } + /** + * Unlinks an identity from a user by deleting it. The user will no longer be able to sign in with that identity once it's unlinked. + */ + async unlinkIdentity(identity) { + try { + return await this._useSession(async (result) => { + var _a, _b; + const { data, error } = result; + if (error) { + throw error; + } + return await (0, fetch_1._request)(this.fetch, 'DELETE', `${this.url}/user/identities/${identity.identity_id}`, { + headers: this.headers, + jwt: (_b = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token) !== null && _b !== void 0 ? _b : undefined, + }); + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: null, error }); } throw error; } @@ -4097,23 +4869,27 @@ class GoTrueClient { const startedAt = Date.now(); // will attempt to refresh the token with exponential backoff return await (0, helpers_1.retryable)(async (attempt) => { - await (0, helpers_1.sleep)(attempt * 200); // 0, 200, 400, 800, ... + if (attempt > 0) { + await (0, helpers_1.sleep)(200 * Math.pow(2, attempt - 1)); // 200, 400, 800, ... + } this._debug(debugName, 'refreshing attempt', attempt); return await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/token?grant_type=refresh_token`, { body: { refresh_token: refreshToken }, headers: this.headers, xform: fetch_1._sessionResponse, }); - }, (attempt, _, result) => result && - result.error && - (0, errors_1.isAuthRetryableFetchError)(result.error) && - // retryable only if the request can be sent before the backoff overflows the tick duration - Date.now() + (attempt + 1) * 200 - startedAt < AUTO_REFRESH_TICK_DURATION); + }, (attempt, error) => { + const nextBackOffInterval = 200 * Math.pow(2, attempt); + return (error && + (0, errors_1.isAuthRetryableFetchError)(error) && + // retryable only if the request can be sent before the backoff overflows the tick duration + Date.now() + nextBackOffInterval - startedAt < constants_1.AUTO_REFRESH_TICK_DURATION_MS); + }); } catch (error) { this._debug(debugName, 'error', error); if ((0, errors_1.isAuthError)(error)) { - return { data: { session: null, user: null }, error }; + return this._returnResult({ data: { session: null, user: null }, error }); } throw error; } @@ -4130,7 +4906,7 @@ class GoTrueClient { return isValidSession; } async _handleProviderSignIn(provider, options) { - const url = await this._getUrlForProvider(provider, { + const url = await this._getUrlForProvider(`${this.url}/authorize`, provider, { redirectTo: options.redirectTo, scopes: options.scopes, queryParams: options.queryParams, @@ -4143,15 +4919,43 @@ class GoTrueClient { return { data: { provider, url }, error: null }; } /** - * Recovers the session from LocalStorage and refreshes + * Recovers the session from LocalStorage and refreshes the token * Note: this method is async to accommodate for AsyncStorage e.g. in React native. */ async _recoverAndRefresh() { - var _a; + var _a, _b; const debugName = '#_recoverAndRefresh()'; this._debug(debugName, 'begin'); try { - const currentSession = await (0, helpers_1.getItemAsync)(this.storage, this.storageKey); + const currentSession = (await (0, helpers_1.getItemAsync)(this.storage, this.storageKey)); + if (currentSession && this.userStorage) { + let maybeUser = (await (0, helpers_1.getItemAsync)(this.userStorage, this.storageKey + '-user')); + if (!this.storage.isServer && Object.is(this.storage, this.userStorage) && !maybeUser) { + // storage and userStorage are the same storage medium, for example + // window.localStorage if userStorage does not have the user from + // storage stored, store it first thereby migrating the user object + // from storage -> userStorage + maybeUser = { user: currentSession.user }; + await (0, helpers_1.setItemAsync)(this.userStorage, this.storageKey + '-user', maybeUser); + } + currentSession.user = (_a = maybeUser === null || maybeUser === void 0 ? void 0 : maybeUser.user) !== null && _a !== void 0 ? _a : (0, helpers_1.userNotAvailableProxy)(); + } + else if (currentSession && !currentSession.user) { + // user storage is not set, let's check if it was previously enabled so + // we bring back the storage as it should be + if (!currentSession.user) { + // test if userStorage was previously enabled and the storage medium was the same, to move the user back under the same key + const separateUser = (await (0, helpers_1.getItemAsync)(this.storage, this.storageKey + '-user')); + if (separateUser && (separateUser === null || separateUser === void 0 ? void 0 : separateUser.user)) { + currentSession.user = separateUser.user; + await (0, helpers_1.removeItemAsync)(this.storage, this.storageKey + '-user'); + await (0, helpers_1.setItemAsync)(this.storage, this.storageKey, currentSession); + } + else { + currentSession.user = (0, helpers_1.userNotAvailableProxy)(); + } + } + } this._debug(debugName, 'session from storage', currentSession); if (!this._isValidSession(currentSession)) { this._debug(debugName, 'session is not valid'); @@ -4160,9 +4964,8 @@ class GoTrueClient { } return; } - const timeNow = Math.round(Date.now() / 1000); - const expiresWithMargin = ((_a = currentSession.expires_at) !== null && _a !== void 0 ? _a : Infinity) < timeNow + constants_1.EXPIRY_MARGIN; - this._debug(debugName, `session has${expiresWithMargin ? '' : ' not'} expired with margin of ${constants_1.EXPIRY_MARGIN}s`); + const expiresWithMargin = ((_b = currentSession.expires_at) !== null && _b !== void 0 ? _b : Infinity) * 1000 - Date.now() < constants_1.EXPIRY_MARGIN_MS; + this._debug(debugName, `session has${expiresWithMargin ? '' : ' not'} expired with margin of ${constants_1.EXPIRY_MARGIN_MS}s`); if (expiresWithMargin) { if (this.autoRefreshToken && currentSession.refresh_token) { const { error } = await this._callRefreshToken(currentSession.refresh_token); @@ -4175,6 +4978,25 @@ class GoTrueClient { } } } + else if (currentSession.user && + currentSession.user.__isUserNotAvailableProxy === true) { + // If we have a proxy user, try to get the real user data + try { + const { data, error: userError } = await this._getUser(currentSession.access_token); + if (!userError && (data === null || data === void 0 ? void 0 : data.user)) { + currentSession.user = data.user; + await this._saveSession(currentSession); + await this._notifyAllSubscribers('SIGNED_IN', currentSession); + } + else { + this._debug(debugName, 'could not get user data, skipping SIGNED_IN notification'); + } + } + catch (getUserError) { + console.error('Error getting user data:', getUserError); + this._debug(debugName, 'error getting user data, skipping SIGNED_IN notification', getUserError); + } + } else { // no need to persist currentSession again, as we just loaded it from // local storage; persisting it again may overwrite a value saved by @@ -4211,14 +5033,17 @@ class GoTrueClient { throw new errors_1.AuthSessionMissingError(); await this._saveSession(data.session); await this._notifyAllSubscribers('TOKEN_REFRESHED', data.session); - const result = { session: data.session, error: null }; + const result = { data: data.session, error: null }; this.refreshingDeferred.resolve(result); return result; } catch (error) { this._debug(debugName, 'error', error); if ((0, errors_1.isAuthError)(error)) { - const result = { session: null, error }; + const result = { data: null, error }; + if (!(0, errors_1.isAuthRetryableFetchError)(error)) { + await this._removeSession(); + } (_a = this.refreshingDeferred) === null || _a === void 0 ? void 0 : _a.resolve(result); return result; } @@ -4264,15 +5089,51 @@ class GoTrueClient { */ async _saveSession(session) { this._debug('#_saveSession()', session); - await this._persistSession(session); - } - _persistSession(currentSession) { - this._debug('#_persistSession()', currentSession); - return (0, helpers_1.setItemAsync)(this.storage, this.storageKey, currentSession); + // _saveSession is always called whenever a new session has been acquired + // so we can safely suppress the warning returned by future getSession calls + this.suppressGetSessionWarning = true; + await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`); + // Create a shallow copy to work with, to avoid mutating the original session object if it's used elsewhere + const sessionToProcess = Object.assign({}, session); + const userIsProxy = sessionToProcess.user && sessionToProcess.user.__isUserNotAvailableProxy === true; + if (this.userStorage) { + if (!userIsProxy && sessionToProcess.user) { + // If it's a real user object, save it to userStorage. + await (0, helpers_1.setItemAsync)(this.userStorage, this.storageKey + '-user', { + user: sessionToProcess.user, + }); + } + else if (userIsProxy) { + // If it's the proxy, it means user was not found in userStorage. + // We should ensure no stale user data for this key exists in userStorage if we were to save null, + // or simply not save the proxy. For now, we don't save the proxy here. + // If there's a need to clear userStorage if user becomes proxy, that logic would go here. + } + // Prepare the main session data for primary storage: remove the user property before cloning + // This is important because the original session.user might be the proxy + const mainSessionData = Object.assign({}, sessionToProcess); + delete mainSessionData.user; // Remove user (real or proxy) before cloning for main storage + const clonedMainSessionData = (0, helpers_1.deepClone)(mainSessionData); + await (0, helpers_1.setItemAsync)(this.storage, this.storageKey, clonedMainSessionData); + } + else { + // No userStorage is configured. + // In this case, session.user should ideally not be a proxy. + // If it were, structuredClone would fail. This implies an issue elsewhere if user is a proxy here + const clonedSession = (0, helpers_1.deepClone)(sessionToProcess); // sessionToProcess still has its original user property + await (0, helpers_1.setItemAsync)(this.storage, this.storageKey, clonedSession); + } } async _removeSession() { this._debug('#_removeSession()'); + this.suppressGetSessionWarning = false; await (0, helpers_1.removeItemAsync)(this.storage, this.storageKey); + await (0, helpers_1.removeItemAsync)(this.storage, this.storageKey + '-code-verifier'); + await (0, helpers_1.removeItemAsync)(this.storage, this.storageKey + '-user'); + if (this.userStorage) { + await (0, helpers_1.removeItemAsync)(this.userStorage, this.storageKey + '-user'); + } + await this._notifyAllSubscribers('SIGNED_OUT', null); } /** * Removes any registered visibilitychange callback. @@ -4300,7 +5161,7 @@ class GoTrueClient { async _startAutoRefresh() { await this._stopAutoRefresh(); this._debug('#_startAutoRefresh()'); - const ticker = setInterval(() => this._autoRefreshTokenTick(), AUTO_REFRESH_TICK_DURATION); + const ticker = setInterval(() => this._autoRefreshTokenTick(), constants_1.AUTO_REFRESH_TICK_DURATION_MS); this.autoRefreshTicker = ticker; if (ticker && typeof ticker === 'object' && typeof ticker.unref === 'function') { // ticker is a NodeJS Timeout object that has an `unref` method @@ -4310,21 +5171,30 @@ class GoTrueClient { // finished and tests run endlessly. This can be prevented by calling // `unref()` on the returned object. ticker.unref(); - // @ts-ignore + // @ts-expect-error TS has no context of Deno } else if (typeof Deno !== 'undefined' && typeof Deno.unrefTimer === 'function') { // similar like for NodeJS, but with the Deno API // https://deno.land/api@latest?unstable&s=Deno.unrefTimer - // @ts-ignore + // @ts-expect-error TS has no context of Deno Deno.unrefTimer(ticker); } // run the tick immediately, but in the next pass of the event loop so that // #_initialize can be allowed to complete without recursively waiting on // itself - setTimeout(async () => { + const timeout = setTimeout(async () => { await this.initializePromise; await this._autoRefreshTokenTick(); }, 0); + this.autoRefreshTickTimeout = timeout; + if (timeout && typeof timeout === 'object' && typeof timeout.unref === 'function') { + timeout.unref(); + // @ts-expect-error TS has no context of Deno + } + else if (typeof Deno !== 'undefined' && typeof Deno.unrefTimer === 'function') { + // @ts-expect-error TS has no context of Deno + Deno.unrefTimer(timeout); + } } /** * This is the private implementation of {@link #stopAutoRefresh}. Use this @@ -4337,6 +5207,11 @@ class GoTrueClient { if (ticker) { clearInterval(ticker); } + const timeout = this.autoRefreshTickTimeout; + this.autoRefreshTickTimeout = null; + if (timeout) { + clearTimeout(timeout); + } } /** * Starts an auto-refresh process in the background. The session is checked @@ -4393,9 +5268,9 @@ class GoTrueClient { return; } // session will expire in this many ticks (or has already expired if <= 0) - const expiresInTicks = Math.floor((session.expires_at * 1000 - now) / AUTO_REFRESH_TICK_DURATION); - this._debug('#_autoRefreshTokenTick()', `access token expires in ${expiresInTicks} ticks, a tick lasts ${AUTO_REFRESH_TICK_DURATION}ms, refresh threshold is ${AUTO_REFRESH_TICK_THRESHOLD} ticks`); - if (expiresInTicks <= AUTO_REFRESH_TICK_THRESHOLD) { + const expiresInTicks = Math.floor((session.expires_at * 1000 - now) / constants_1.AUTO_REFRESH_TICK_DURATION_MS); + this._debug('#_autoRefreshTokenTick()', `access token expires in ${expiresInTicks} ticks, a tick lasts ${constants_1.AUTO_REFRESH_TICK_DURATION_MS}ms, refresh threshold is ${constants_1.AUTO_REFRESH_TICK_THRESHOLD} ticks`); + if (expiresInTicks <= constants_1.AUTO_REFRESH_TICK_THRESHOLD) { await this._callRefreshToken(session.refresh_token); } }); @@ -4433,7 +5308,14 @@ class GoTrueClient { return false; } try { - this.visibilityChangedCallback = async () => await this._onVisibilityChanged(false); + this.visibilityChangedCallback = async () => { + try { + await this._onVisibilityChanged(false); + } + catch (error) { + this._debug('#visibilityChangedCallback', 'error', error); + } + }; window === null || window === void 0 ? void 0 : window.addEventListener('visibilitychange', this.visibilityChangedCallback); // now immediately call the visbility changed callback to setup with the // current visbility state @@ -4461,7 +5343,7 @@ class GoTrueClient { // should be recovered immediately... but to do that we need to acquire // the lock first asynchronously await this.initializePromise; - await this._acquireLock(-1, async () => { + await this._acquireLock(this.lockAcquireTimeout, async () => { if (document.visibilityState !== 'visible') { this._debug(methodName, 'acquired the lock to recover the session, but the browser visibilityState is no longer visible, aborting'); // visibility has changed while waiting for the lock, abort @@ -4484,7 +5366,7 @@ class GoTrueClient { * @param options.scopes A space-separated list of scopes granted to the OAuth application. * @param options.queryParams An object of key-value pairs containing query parameters granted to the OAuth application. */ - async _getUrlForProvider(provider, options) { + async _getUrlForProvider(url, provider, options) { const urlParams = [`provider=${encodeURIComponent(provider)}`]; if (options === null || options === void 0 ? void 0 : options.redirectTo) { urlParams.push(`redirect_to=${encodeURIComponent(options.redirectTo)}`); @@ -4493,11 +5375,7 @@ class GoTrueClient { urlParams.push(`scopes=${encodeURIComponent(options.scopes)}`); } if (this.flowType === 'pkce') { - const codeVerifier = (0, helpers_1.generatePKCEVerifier)(); - await (0, helpers_1.setItemAsync)(this.storage, `${this.storageKey}-code-verifier`, codeVerifier); - const codeChallenge = await (0, helpers_1.generatePKCEChallenge)(codeVerifier); - const codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256'; - this._debug('PKCE', 'code verifier', `${codeVerifier.substring(0, 5)}...`, 'code challenge', codeChallenge, 'method', codeChallengeMethod); + const [codeChallenge, codeChallengeMethod] = await (0, helpers_1.getCodeChallengeAndMethod)(this.storage, this.storageKey); const flowParams = new URLSearchParams({ code_challenge: `${encodeURIComponent(codeChallenge)}`, code_challenge_method: `${encodeURIComponent(codeChallengeMethod)}`, @@ -4508,7 +5386,10 @@ class GoTrueClient { const query = new URLSearchParams(options.queryParams); urlParams.push(query.toString()); } - return `${this.url}/authorize?${urlParams.join('&')}`; + if (options === null || options === void 0 ? void 0 : options.skipBrowserRedirect) { + urlParams.push(`skip_http_redirect=${options.skipBrowserRedirect}`); + } + return `${url}?${urlParams.join('&')}`; } async _unenroll(params) { try { @@ -4516,7 +5397,7 @@ class GoTrueClient { var _a; const { data: sessionData, error: sessionError } = result; if (sessionError) { - return { data: null, error: sessionError }; + return this._returnResult({ data: null, error: sessionError }); } return await (0, fetch_1._request)(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, { headers: this.headers, @@ -4526,101 +5407,120 @@ class GoTrueClient { } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { data: null, error }; + return this._returnResult({ data: null, error }); } throw error; } } - /** - * {@see GoTrueMFAApi#enroll} - */ async _enroll(params) { try { return await this._useSession(async (result) => { var _a, _b; const { data: sessionData, error: sessionError } = result; if (sessionError) { - return { data: null, error: sessionError }; + return this._returnResult({ data: null, error: sessionError }); } - const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors`, { - body: { - friendly_name: params.friendlyName, - factor_type: params.factorType, - issuer: params.issuer, - }, + const body = Object.assign({ friendly_name: params.friendlyName, factor_type: params.factorType }, (params.factorType === 'phone' + ? { phone: params.phone } + : params.factorType === 'totp' + ? { issuer: params.issuer } + : {})); + const { data, error } = (await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors`, { + body, headers: this.headers, jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token, - }); + })); if (error) { - return { data: null, error }; + return this._returnResult({ data: null, error }); } - if ((_b = data === null || data === void 0 ? void 0 : data.totp) === null || _b === void 0 ? void 0 : _b.qr_code) { + if (params.factorType === 'totp' && data.type === 'totp' && ((_b = data === null || data === void 0 ? void 0 : data.totp) === null || _b === void 0 ? void 0 : _b.qr_code)) { data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`; } - return { data, error: null }; + return this._returnResult({ data, error: null }); }); } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { data: null, error }; + return this._returnResult({ data: null, error }); } throw error; } } - /** - * {@see GoTrueMFAApi#verify} - */ async _verify(params) { - return this._acquireLock(-1, async () => { + return this._acquireLock(this.lockAcquireTimeout, async () => { try { return await this._useSession(async (result) => { var _a; const { data: sessionData, error: sessionError } = result; if (sessionError) { - return { data: null, error: sessionError }; + return this._returnResult({ data: null, error: sessionError }); } + const body = Object.assign({ challenge_id: params.challengeId }, ('webauthn' in params + ? { + webauthn: Object.assign(Object.assign({}, params.webauthn), { credential_response: params.webauthn.type === 'create' + ? (0, webauthn_1.serializeCredentialCreationResponse)(params.webauthn.credential_response) + : (0, webauthn_1.serializeCredentialRequestResponse)(params.webauthn.credential_response) }), + } + : { code: params.code })); const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/verify`, { - body: { code: params.code, challenge_id: params.challengeId }, + body, headers: this.headers, jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token, }); if (error) { - return { data: null, error }; + return this._returnResult({ data: null, error }); } await this._saveSession(Object.assign({ expires_at: Math.round(Date.now() / 1000) + data.expires_in }, data)); await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data); - return { data, error }; + return this._returnResult({ data, error }); }); } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { data: null, error }; + return this._returnResult({ data: null, error }); } throw error; } }); } - /** - * {@see GoTrueMFAApi#challenge} - */ async _challenge(params) { - return this._acquireLock(-1, async () => { + return this._acquireLock(this.lockAcquireTimeout, async () => { try { return await this._useSession(async (result) => { var _a; const { data: sessionData, error: sessionError } = result; if (sessionError) { - return { data: null, error: sessionError }; + return this._returnResult({ data: null, error: sessionError }); } - return await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/challenge`, { + const response = (await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/challenge`, { + body: params, headers: this.headers, jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token, - }); + })); + if (response.error) { + return response; + } + const { data } = response; + if (data.type !== 'webauthn') { + return { data, error: null }; + } + switch (data.webauthn.type) { + case 'create': + return { + data: Object.assign(Object.assign({}, data), { webauthn: Object.assign(Object.assign({}, data.webauthn), { credential_options: Object.assign(Object.assign({}, data.webauthn.credential_options), { publicKey: (0, webauthn_1.deserializeCredentialCreationOptions)(data.webauthn.credential_options.publicKey) }) }) }), + error: null, + }; + case 'request': + return { + data: Object.assign(Object.assign({}, data), { webauthn: Object.assign(Object.assign({}, data.webauthn), { credential_options: Object.assign(Object.assign({}, data.webauthn.credential_options), { publicKey: (0, webauthn_1.deserializeCredentialRequestOptions)(data.webauthn.credential_options.publicKey) }) }) }), + error: null, + }; + } }); } catch (error) { if ((0, errors_1.isAuthError)(error)) { - return { data: null, error }; + return this._returnResult({ data: null, error }); } throw error; } @@ -4636,7 +5536,7 @@ class GoTrueClient { factorId: params.factorId, }); if (challengeError) { - return { data: null, error: challengeError }; + return this._returnResult({ data: null, error: challengeError }); } return await this._verify({ factorId: params.factorId, @@ -4648,158 +5548,780 @@ class GoTrueClient { * {@see GoTrueMFAApi#listFactors} */ async _listFactors() { + var _a; // use #getUser instead of #_getUser as the former acquires a lock const { data: { user }, error: userError, } = await this.getUser(); if (userError) { return { data: null, error: userError }; } - const factors = (user === null || user === void 0 ? void 0 : user.factors) || []; - const totp = factors.filter((factor) => factor.factor_type === 'totp' && factor.status === 'verified'); + const data = { + all: [], + phone: [], + totp: [], + webauthn: [], + }; + // loop over the factors ONCE + for (const factor of (_a = user === null || user === void 0 ? void 0 : user.factors) !== null && _a !== void 0 ? _a : []) { + data.all.push(factor); + if (factor.status === 'verified') { + ; + data[factor.factor_type].push(factor); + } + } return { - data: { - all: factors, - totp, - }, + data, error: null, }; } /** * {@see GoTrueMFAApi#getAuthenticatorAssuranceLevel} */ - async _getAuthenticatorAssuranceLevel() { - return this._acquireLock(-1, async () => { - return await this._useSession(async (result) => { - var _a, _b; - const { data: { session }, error: sessionError, } = result; - if (sessionError) { - return { data: null, error: sessionError }; - } - if (!session) { - return { - data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] }, - error: null, - }; - } - const payload = this._decodeJWT(session.access_token); + async _getAuthenticatorAssuranceLevel(jwt) { + var _a, _b, _c, _d; + if (jwt) { + try { + const { payload } = (0, helpers_1.decodeJWT)(jwt); let currentLevel = null; if (payload.aal) { currentLevel = payload.aal; } let nextLevel = currentLevel; - const verifiedFactors = (_b = (_a = session.user.factors) === null || _a === void 0 ? void 0 : _a.filter((factor) => factor.status === 'verified')) !== null && _b !== void 0 ? _b : []; + const { data: { user }, error: userError, } = await this.getUser(jwt); + if (userError) { + return this._returnResult({ data: null, error: userError }); + } + const verifiedFactors = (_b = (_a = user === null || user === void 0 ? void 0 : user.factors) === null || _a === void 0 ? void 0 : _a.filter((factor) => factor.status === 'verified')) !== null && _b !== void 0 ? _b : []; if (verifiedFactors.length > 0) { nextLevel = 'aal2'; } const currentAuthenticationMethods = payload.amr || []; return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null }; + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: null, error }); + } + throw error; + } + } + const { data: { session }, error: sessionError, } = await this.getSession(); + if (sessionError) { + return this._returnResult({ data: null, error: sessionError }); + } + if (!session) { + return { + data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] }, + error: null, + }; + } + const { payload } = (0, helpers_1.decodeJWT)(session.access_token); + let currentLevel = null; + if (payload.aal) { + currentLevel = payload.aal; + } + let nextLevel = currentLevel; + const verifiedFactors = (_d = (_c = session.user.factors) === null || _c === void 0 ? void 0 : _c.filter((factor) => factor.status === 'verified')) !== null && _d !== void 0 ? _d : []; + if (verifiedFactors.length > 0) { + nextLevel = 'aal2'; + } + const currentAuthenticationMethods = payload.amr || []; + return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null }; + } + /** + * Retrieves details about an OAuth authorization request. + * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. + * + * Returns authorization details including client info, scopes, and user information. + * If the response includes only a redirect_url field, it means consent was already given - the caller + * should handle the redirect manually if needed. + */ + async _getAuthorizationDetails(authorizationId) { + try { + return await this._useSession(async (result) => { + const { data: { session }, error: sessionError, } = result; + if (sessionError) { + return this._returnResult({ data: null, error: sessionError }); + } + if (!session) { + return this._returnResult({ data: null, error: new errors_1.AuthSessionMissingError() }); + } + return await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/oauth/authorizations/${authorizationId}`, { + headers: this.headers, + jwt: session.access_token, + xform: (data) => ({ data, error: null }), + }); + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: null, error }); + } + throw error; + } + } + /** + * Approves an OAuth authorization request. + * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. + */ + async _approveAuthorization(authorizationId, options) { + try { + return await this._useSession(async (result) => { + const { data: { session }, error: sessionError, } = result; + if (sessionError) { + return this._returnResult({ data: null, error: sessionError }); + } + if (!session) { + return this._returnResult({ data: null, error: new errors_1.AuthSessionMissingError() }); + } + const response = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/oauth/authorizations/${authorizationId}/consent`, { + headers: this.headers, + jwt: session.access_token, + body: { action: 'approve' }, + xform: (data) => ({ data, error: null }), + }); + if (response.data && response.data.redirect_url) { + // Automatically redirect in browser unless skipBrowserRedirect is true + if ((0, helpers_1.isBrowser)() && !(options === null || options === void 0 ? void 0 : options.skipBrowserRedirect)) { + window.location.assign(response.data.redirect_url); + } + } + return response; + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: null, error }); + } + throw error; + } + } + /** + * Denies an OAuth authorization request. + * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. + */ + async _denyAuthorization(authorizationId, options) { + try { + return await this._useSession(async (result) => { + const { data: { session }, error: sessionError, } = result; + if (sessionError) { + return this._returnResult({ data: null, error: sessionError }); + } + if (!session) { + return this._returnResult({ data: null, error: new errors_1.AuthSessionMissingError() }); + } + const response = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/oauth/authorizations/${authorizationId}/consent`, { + headers: this.headers, + jwt: session.access_token, + body: { action: 'deny' }, + xform: (data) => ({ data, error: null }), + }); + if (response.data && response.data.redirect_url) { + // Automatically redirect in browser unless skipBrowserRedirect is true + if ((0, helpers_1.isBrowser)() && !(options === null || options === void 0 ? void 0 : options.skipBrowserRedirect)) { + window.location.assign(response.data.redirect_url); + } + } + return response; + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: null, error }); + } + throw error; + } + } + /** + * Lists all OAuth grants that the authenticated user has authorized. + * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. + */ + async _listOAuthGrants() { + try { + return await this._useSession(async (result) => { + const { data: { session }, error: sessionError, } = result; + if (sessionError) { + return this._returnResult({ data: null, error: sessionError }); + } + if (!session) { + return this._returnResult({ data: null, error: new errors_1.AuthSessionMissingError() }); + } + return await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/user/oauth/grants`, { + headers: this.headers, + jwt: session.access_token, + xform: (data) => ({ data, error: null }), + }); + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: null, error }); + } + throw error; + } + } + /** + * Revokes a user's OAuth grant for a specific client. + * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. + */ + async _revokeOAuthGrant(options) { + try { + return await this._useSession(async (result) => { + const { data: { session }, error: sessionError, } = result; + if (sessionError) { + return this._returnResult({ data: null, error: sessionError }); + } + if (!session) { + return this._returnResult({ data: null, error: new errors_1.AuthSessionMissingError() }); + } + await (0, fetch_1._request)(this.fetch, 'DELETE', `${this.url}/user/oauth/grants`, { + headers: this.headers, + jwt: session.access_token, + query: { client_id: options.clientId }, + noResolveJson: true, + }); + return { data: {}, error: null }; }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: null, error }); + } + throw error; + } + } + async fetchJwk(kid, jwks = { keys: [] }) { + // try fetching from the supplied jwks + let jwk = jwks.keys.find((key) => key.kid === kid); + if (jwk) { + return jwk; + } + const now = Date.now(); + // try fetching from cache + jwk = this.jwks.keys.find((key) => key.kid === kid); + // jwk exists and jwks isn't stale + if (jwk && this.jwks_cached_at + constants_1.JWKS_TTL > now) { + return jwk; + } + // jwk isn't cached in memory so we need to fetch it from the well-known endpoint + const { data, error } = await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/.well-known/jwks.json`, { + headers: this.headers, }); + if (error) { + throw error; + } + if (!data.keys || data.keys.length === 0) { + return null; + } + this.jwks = data; + this.jwks_cached_at = now; + // Find the signing key + jwk = data.keys.find((key) => key.kid === kid); + if (!jwk) { + return null; + } + return jwk; + } + /** + * Extracts the JWT claims present in the access token by first verifying the + * JWT against the server's JSON Web Key Set endpoint + * `/.well-known/jwks.json` which is often cached, resulting in significantly + * faster responses. Prefer this method over {@link #getUser} which always + * sends a request to the Auth server for each JWT. + * + * If the project is not using an asymmetric JWT signing key (like ECC or + * RSA) it always sends a request to the Auth server (similar to {@link + * #getUser}) to verify the JWT. + * + * @param jwt An optional specific JWT you wish to verify, not the one you + * can obtain from {@link #getSession}. + * @param options Various additional options that allow you to customize the + * behavior of this method. + */ + async getClaims(jwt, options = {}) { + try { + let token = jwt; + if (!token) { + const { data, error } = await this.getSession(); + if (error || !data.session) { + return this._returnResult({ data: null, error }); + } + token = data.session.access_token; + } + const { header, payload, signature, raw: { header: rawHeader, payload: rawPayload }, } = (0, helpers_1.decodeJWT)(token); + if (!(options === null || options === void 0 ? void 0 : options.allowExpired)) { + // Reject expired JWTs should only happen if jwt argument was passed + (0, helpers_1.validateExp)(payload.exp); + } + const signingKey = !header.alg || + header.alg.startsWith('HS') || + !header.kid || + !('crypto' in globalThis && 'subtle' in globalThis.crypto) + ? null + : await this.fetchJwk(header.kid, (options === null || options === void 0 ? void 0 : options.keys) ? { keys: options.keys } : options === null || options === void 0 ? void 0 : options.jwks); + // If symmetric algorithm or WebCrypto API is unavailable, fallback to getUser() + if (!signingKey) { + const { error } = await this.getUser(token); + if (error) { + throw error; + } + // getUser succeeds so the claims in the JWT can be trusted + return { + data: { + claims: payload, + header, + signature, + }, + error: null, + }; + } + const algorithm = (0, helpers_1.getAlgorithm)(header.alg); + // Convert JWK to CryptoKey + const publicKey = await crypto.subtle.importKey('jwk', signingKey, algorithm, true, [ + 'verify', + ]); + // Verify the signature + const isValid = await crypto.subtle.verify(algorithm, publicKey, signature, (0, base64url_1.stringToUint8Array)(`${rawHeader}.${rawPayload}`)); + if (!isValid) { + throw new errors_1.AuthInvalidJwtError('Invalid JWT signature'); + } + // If verification succeeds, decode and return claims + return { + data: { + claims: payload, + header, + signature, + }, + error: null, + }; + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return this._returnResult({ data: null, error }); + } + throw error; + } } } +GoTrueClient.nextInstanceID = {}; exports["default"] = GoTrueClient; -GoTrueClient.nextInstanceID = 0; //# sourceMappingURL=GoTrueClient.js.map /***/ }), -/***/ 60: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 6748: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __exportStar = (this && this.__exportStar) || function(m, exports) { - for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.lockInternals = exports.NavigatorLockAcquireTimeoutError = exports.navigatorLock = exports.GoTrueClient = exports.GoTrueAdminApi = void 0; -const GoTrueAdminApi_1 = __importDefault(__nccwpck_require__(4599)); +exports.processLock = exports.lockInternals = exports.NavigatorLockAcquireTimeoutError = exports.navigatorLock = exports.AuthClient = exports.AuthAdminApi = exports.GoTrueClient = exports.GoTrueAdminApi = void 0; +const tslib_1 = __nccwpck_require__(9808); +const GoTrueAdminApi_1 = tslib_1.__importDefault(__nccwpck_require__(6575)); exports.GoTrueAdminApi = GoTrueAdminApi_1.default; -const GoTrueClient_1 = __importDefault(__nccwpck_require__(7139)); +const GoTrueClient_1 = tslib_1.__importDefault(__nccwpck_require__(313)); exports.GoTrueClient = GoTrueClient_1.default; -__exportStar(__nccwpck_require__(5739), exports); -__exportStar(__nccwpck_require__(6723), exports); -var locks_1 = __nccwpck_require__(7000); +const AuthAdminApi_1 = tslib_1.__importDefault(__nccwpck_require__(9809)); +exports.AuthAdminApi = AuthAdminApi_1.default; +const AuthClient_1 = tslib_1.__importDefault(__nccwpck_require__(4525)); +exports.AuthClient = AuthClient_1.default; +tslib_1.__exportStar(__nccwpck_require__(1852), exports); +tslib_1.__exportStar(__nccwpck_require__(9938), exports); +var locks_1 = __nccwpck_require__(163); Object.defineProperty(exports, "navigatorLock", ({ enumerable: true, get: function () { return locks_1.navigatorLock; } })); Object.defineProperty(exports, "NavigatorLockAcquireTimeoutError", ({ enumerable: true, get: function () { return locks_1.NavigatorLockAcquireTimeoutError; } })); Object.defineProperty(exports, "lockInternals", ({ enumerable: true, get: function () { return locks_1.internals; } })); +Object.defineProperty(exports, "processLock", ({ enumerable: true, get: function () { return locks_1.processLock; } })); //# sourceMappingURL=index.js.map /***/ }), -/***/ 2496: +/***/ 3649: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +/** + * Avoid modifying this file. It's part of + * https://github.com/supabase-community/base64url-js. Submit all fixes on + * that repo! + */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.byteToBase64URL = byteToBase64URL; +exports.byteFromBase64URL = byteFromBase64URL; +exports.stringToBase64URL = stringToBase64URL; +exports.stringFromBase64URL = stringFromBase64URL; +exports.codepointToUTF8 = codepointToUTF8; +exports.stringToUTF8 = stringToUTF8; +exports.stringFromUTF8 = stringFromUTF8; +exports.base64UrlToUint8Array = base64UrlToUint8Array; +exports.stringToUint8Array = stringToUint8Array; +exports.bytesToBase64URL = bytesToBase64URL; +/** + * An array of characters that encode 6 bits into a Base64-URL alphabet + * character. + */ +const TO_BASE64URL = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'.split(''); +/** + * An array of characters that can appear in a Base64-URL encoded string but + * should be ignored. + */ +const IGNORE_BASE64URL = ' \t\n\r='.split(''); +/** + * An array of 128 numbers that map a Base64-URL character to 6 bits, or if -2 + * used to skip the character, or if -1 used to error out. + */ +const FROM_BASE64URL = (() => { + const charMap = new Array(128); + for (let i = 0; i < charMap.length; i += 1) { + charMap[i] = -1; + } + for (let i = 0; i < IGNORE_BASE64URL.length; i += 1) { + charMap[IGNORE_BASE64URL[i].charCodeAt(0)] = -2; + } + for (let i = 0; i < TO_BASE64URL.length; i += 1) { + charMap[TO_BASE64URL[i].charCodeAt(0)] = i; + } + return charMap; +})(); +/** + * Converts a byte to a Base64-URL string. + * + * @param byte The byte to convert, or null to flush at the end of the byte sequence. + * @param state The Base64 conversion state. Pass an initial value of `{ queue: 0, queuedBits: 0 }`. + * @param emit A function called with the next Base64 character when ready. + */ +function byteToBase64URL(byte, state, emit) { + if (byte !== null) { + state.queue = (state.queue << 8) | byte; + state.queuedBits += 8; + while (state.queuedBits >= 6) { + const pos = (state.queue >> (state.queuedBits - 6)) & 63; + emit(TO_BASE64URL[pos]); + state.queuedBits -= 6; + } + } + else if (state.queuedBits > 0) { + state.queue = state.queue << (6 - state.queuedBits); + state.queuedBits = 6; + while (state.queuedBits >= 6) { + const pos = (state.queue >> (state.queuedBits - 6)) & 63; + emit(TO_BASE64URL[pos]); + state.queuedBits -= 6; + } + } +} +/** + * Converts a String char code (extracted using `string.charCodeAt(position)`) to a sequence of Base64-URL characters. + * + * @param charCode The char code of the JavaScript string. + * @param state The Base64 state. Pass an initial value of `{ queue: 0, queuedBits: 0 }`. + * @param emit A function called with the next byte. + */ +function byteFromBase64URL(charCode, state, emit) { + const bits = FROM_BASE64URL[charCode]; + if (bits > -1) { + // valid Base64-URL character + state.queue = (state.queue << 6) | bits; + state.queuedBits += 6; + while (state.queuedBits >= 8) { + emit((state.queue >> (state.queuedBits - 8)) & 0xff); + state.queuedBits -= 8; + } + } + else if (bits === -2) { + // ignore spaces, tabs, newlines, = + return; + } + else { + throw new Error(`Invalid Base64-URL character "${String.fromCharCode(charCode)}"`); + } +} +/** + * Converts a JavaScript string (which may include any valid character) into a + * Base64-URL encoded string. The string is first encoded in UTF-8 which is + * then encoded as Base64-URL. + * + * @param str The string to convert. + */ +function stringToBase64URL(str) { + const base64 = []; + const emitter = (char) => { + base64.push(char); + }; + const state = { queue: 0, queuedBits: 0 }; + stringToUTF8(str, (byte) => { + byteToBase64URL(byte, state, emitter); + }); + byteToBase64URL(null, state, emitter); + return base64.join(''); +} +/** + * Converts a Base64-URL encoded string into a JavaScript string. It is assumed + * that the underlying string has been encoded as UTF-8. + * + * @param str The Base64-URL encoded string. + */ +function stringFromBase64URL(str) { + const conv = []; + const utf8Emit = (codepoint) => { + conv.push(String.fromCodePoint(codepoint)); + }; + const utf8State = { + utf8seq: 0, + codepoint: 0, + }; + const b64State = { queue: 0, queuedBits: 0 }; + const byteEmit = (byte) => { + stringFromUTF8(byte, utf8State, utf8Emit); + }; + for (let i = 0; i < str.length; i += 1) { + byteFromBase64URL(str.charCodeAt(i), b64State, byteEmit); + } + return conv.join(''); +} +/** + * Converts a Unicode codepoint to a multi-byte UTF-8 sequence. + * + * @param codepoint The Unicode codepoint. + * @param emit Function which will be called for each UTF-8 byte that represents the codepoint. + */ +function codepointToUTF8(codepoint, emit) { + if (codepoint <= 0x7f) { + emit(codepoint); + return; + } + else if (codepoint <= 0x7ff) { + emit(0xc0 | (codepoint >> 6)); + emit(0x80 | (codepoint & 0x3f)); + return; + } + else if (codepoint <= 0xffff) { + emit(0xe0 | (codepoint >> 12)); + emit(0x80 | ((codepoint >> 6) & 0x3f)); + emit(0x80 | (codepoint & 0x3f)); + return; + } + else if (codepoint <= 0x10ffff) { + emit(0xf0 | (codepoint >> 18)); + emit(0x80 | ((codepoint >> 12) & 0x3f)); + emit(0x80 | ((codepoint >> 6) & 0x3f)); + emit(0x80 | (codepoint & 0x3f)); + return; + } + throw new Error(`Unrecognized Unicode codepoint: ${codepoint.toString(16)}`); +} +/** + * Converts a JavaScript string to a sequence of UTF-8 bytes. + * + * @param str The string to convert to UTF-8. + * @param emit Function which will be called for each UTF-8 byte of the string. + */ +function stringToUTF8(str, emit) { + for (let i = 0; i < str.length; i += 1) { + let codepoint = str.charCodeAt(i); + if (codepoint > 0xd7ff && codepoint <= 0xdbff) { + // most UTF-16 codepoints are Unicode codepoints, except values in this + // range where the next UTF-16 codepoint needs to be combined with the + // current one to get the Unicode codepoint + const highSurrogate = ((codepoint - 0xd800) * 0x400) & 0xffff; + const lowSurrogate = (str.charCodeAt(i + 1) - 0xdc00) & 0xffff; + codepoint = (lowSurrogate | highSurrogate) + 0x10000; + i += 1; + } + codepointToUTF8(codepoint, emit); + } +} +/** + * Converts a UTF-8 byte to a Unicode codepoint. + * + * @param byte The UTF-8 byte next in the sequence. + * @param state The shared state between consecutive UTF-8 bytes in the + * sequence, an object with the shape `{ utf8seq: 0, codepoint: 0 }`. + * @param emit Function which will be called for each codepoint. + */ +function stringFromUTF8(byte, state, emit) { + if (state.utf8seq === 0) { + if (byte <= 0x7f) { + emit(byte); + return; + } + // count the number of 1 leading bits until you reach 0 + for (let leadingBit = 1; leadingBit < 6; leadingBit += 1) { + if (((byte >> (7 - leadingBit)) & 1) === 0) { + state.utf8seq = leadingBit; + break; + } + } + if (state.utf8seq === 2) { + state.codepoint = byte & 31; + } + else if (state.utf8seq === 3) { + state.codepoint = byte & 15; + } + else if (state.utf8seq === 4) { + state.codepoint = byte & 7; + } + else { + throw new Error('Invalid UTF-8 sequence'); + } + state.utf8seq -= 1; + } + else if (state.utf8seq > 0) { + if (byte <= 0x7f) { + throw new Error('Invalid UTF-8 sequence'); + } + state.codepoint = (state.codepoint << 6) | (byte & 63); + state.utf8seq -= 1; + if (state.utf8seq === 0) { + emit(state.codepoint); + } + } +} +/** + * Helper functions to convert different types of strings to Uint8Array + */ +function base64UrlToUint8Array(str) { + const result = []; + const state = { queue: 0, queuedBits: 0 }; + const onByte = (byte) => { + result.push(byte); + }; + for (let i = 0; i < str.length; i += 1) { + byteFromBase64URL(str.charCodeAt(i), state, onByte); + } + return new Uint8Array(result); +} +function stringToUint8Array(str) { + const result = []; + stringToUTF8(str, (byte) => result.push(byte)); + return new Uint8Array(result); +} +function bytesToBase64URL(bytes) { + const result = []; + const state = { queue: 0, queuedBits: 0 }; + const onChar = (char) => { + result.push(char); + }; + bytes.forEach((byte) => byteToBase64URL(byte, state, onChar)); + // always call with `null` after processing all bytes + byteToBase64URL(null, state, onChar); + return result.join(''); +} +//# sourceMappingURL=base64url.js.map + +/***/ }), + +/***/ 518: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.NETWORK_FAILURE = exports.EXPIRY_MARGIN = exports.DEFAULT_HEADERS = exports.AUDIENCE = exports.STORAGE_KEY = exports.GOTRUE_URL = void 0; -const version_1 = __nccwpck_require__(5910); +exports.JWKS_TTL = exports.BASE64URL_REGEX = exports.API_VERSIONS = exports.API_VERSION_HEADER_NAME = exports.NETWORK_FAILURE = exports.DEFAULT_HEADERS = exports.AUDIENCE = exports.STORAGE_KEY = exports.GOTRUE_URL = exports.EXPIRY_MARGIN_MS = exports.AUTO_REFRESH_TICK_THRESHOLD = exports.AUTO_REFRESH_TICK_DURATION_MS = void 0; +const version_1 = __nccwpck_require__(6677); +/** Current session will be checked for refresh at this interval. */ +exports.AUTO_REFRESH_TICK_DURATION_MS = 30 * 1000; +/** + * A token refresh will be attempted this many ticks before the current session expires. */ +exports.AUTO_REFRESH_TICK_THRESHOLD = 3; +/* + * Earliest time before an access token expires that the session should be refreshed. + */ +exports.EXPIRY_MARGIN_MS = exports.AUTO_REFRESH_TICK_THRESHOLD * exports.AUTO_REFRESH_TICK_DURATION_MS; exports.GOTRUE_URL = 'http://localhost:9999'; exports.STORAGE_KEY = 'supabase.auth.token'; exports.AUDIENCE = ''; exports.DEFAULT_HEADERS = { 'X-Client-Info': `gotrue-js/${version_1.version}` }; -exports.EXPIRY_MARGIN = 10; // in seconds exports.NETWORK_FAILURE = { MAX_RETRIES: 10, RETRY_INTERVAL: 2, // in deciseconds }; +exports.API_VERSION_HEADER_NAME = 'X-Supabase-Api-Version'; +exports.API_VERSIONS = { + '2024-01-01': { + timestamp: Date.parse('2024-01-01T00:00:00.0Z'), + name: '2024-01-01', + }, +}; +exports.BASE64URL_REGEX = /^([a-z0-9_-]{4})*($|[a-z0-9_-]{3}$|[a-z0-9_-]{2}$)$/i; +exports.JWKS_TTL = 10 * 60 * 1000; // 10 minutes //# sourceMappingURL=constants.js.map /***/ }), -/***/ 6723: +/***/ 9938: /***/ ((__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.isAuthRetryableFetchError = exports.AuthRetryableFetchError = exports.AuthPKCEGrantCodeExchangeError = exports.AuthImplicitGrantRedirectError = exports.AuthInvalidCredentialsError = exports.AuthInvalidTokenResponseError = exports.AuthSessionMissingError = exports.CustomAuthError = exports.AuthUnknownError = exports.isAuthApiError = exports.AuthApiError = exports.isAuthError = exports.AuthError = void 0; +exports.AuthInvalidJwtError = exports.AuthWeakPasswordError = exports.AuthRetryableFetchError = exports.AuthPKCECodeVerifierMissingError = exports.AuthPKCEGrantCodeExchangeError = exports.AuthImplicitGrantRedirectError = exports.AuthInvalidCredentialsError = exports.AuthInvalidTokenResponseError = exports.AuthSessionMissingError = exports.CustomAuthError = exports.AuthUnknownError = exports.AuthApiError = exports.AuthError = void 0; +exports.isAuthError = isAuthError; +exports.isAuthApiError = isAuthApiError; +exports.isAuthSessionMissingError = isAuthSessionMissingError; +exports.isAuthImplicitGrantRedirectError = isAuthImplicitGrantRedirectError; +exports.isAuthPKCECodeVerifierMissingError = isAuthPKCECodeVerifierMissingError; +exports.isAuthRetryableFetchError = isAuthRetryableFetchError; +exports.isAuthWeakPasswordError = isAuthWeakPasswordError; +/** + * Base error thrown by Supabase Auth helpers. + * + * @example + * ```ts + * import { AuthError } from '@supabase/auth-js' + * + * throw new AuthError('Unexpected auth error', 500, 'unexpected') + * ``` + */ class AuthError extends Error { - constructor(message, status) { + constructor(message, status, code) { super(message); this.__isAuthError = true; this.name = 'AuthError'; this.status = status; + this.code = code; } } exports.AuthError = AuthError; function isAuthError(error) { return typeof error === 'object' && error !== null && '__isAuthError' in error; } -exports.isAuthError = isAuthError; +/** + * Error returned directly from the GoTrue REST API. + * + * @example + * ```ts + * import { AuthApiError } from '@supabase/auth-js' + * + * throw new AuthApiError('Invalid credentials', 400, 'invalid_credentials') + * ``` + */ class AuthApiError extends AuthError { - constructor(message, status) { - super(message, status); + constructor(message, status, code) { + super(message, status, code); this.name = 'AuthApiError'; this.status = status; - } - toJSON() { - return { - name: this.name, - message: this.message, - status: this.status, - }; + this.code = code; } } exports.AuthApiError = AuthApiError; function isAuthApiError(error) { return isAuthError(error) && error.name === 'AuthApiError'; } -exports.isAuthApiError = isAuthApiError; +/** + * Wraps non-standard errors so callers can inspect the root cause. + * + * @example + * ```ts + * import { AuthUnknownError } from '@supabase/auth-js' + * + * try { + * await someAuthCall() + * } catch (err) { + * throw new AuthUnknownError('Auth failed', err) + * } + * ``` + */ class AuthUnknownError extends AuthError { constructor(message, originalError) { super(message); @@ -4808,42 +6330,91 @@ class AuthUnknownError extends AuthError { } } exports.AuthUnknownError = AuthUnknownError; +/** + * Flexible error class used to create named auth errors at runtime. + * + * @example + * ```ts + * import { CustomAuthError } from '@supabase/auth-js' + * + * throw new CustomAuthError('My custom auth error', 'MyAuthError', 400, 'custom_code') + * ``` + */ class CustomAuthError extends AuthError { - constructor(message, name, status) { - super(message); + constructor(message, name, status, code) { + super(message, status, code); this.name = name; this.status = status; } - toJSON() { - return { - name: this.name, - message: this.message, - status: this.status, - }; - } } exports.CustomAuthError = CustomAuthError; +/** + * Error thrown when an operation requires a session but none is present. + * + * @example + * ```ts + * import { AuthSessionMissingError } from '@supabase/auth-js' + * + * throw new AuthSessionMissingError() + * ``` + */ class AuthSessionMissingError extends CustomAuthError { constructor() { - super('Auth session missing!', 'AuthSessionMissingError', 400); + super('Auth session missing!', 'AuthSessionMissingError', 400, undefined); } } exports.AuthSessionMissingError = AuthSessionMissingError; +function isAuthSessionMissingError(error) { + return isAuthError(error) && error.name === 'AuthSessionMissingError'; +} +/** + * Error thrown when the token response is malformed. + * + * @example + * ```ts + * import { AuthInvalidTokenResponseError } from '@supabase/auth-js' + * + * throw new AuthInvalidTokenResponseError() + * ``` + */ class AuthInvalidTokenResponseError extends CustomAuthError { constructor() { - super('Auth session or user missing', 'AuthInvalidTokenResponseError', 500); + super('Auth session or user missing', 'AuthInvalidTokenResponseError', 500, undefined); } } exports.AuthInvalidTokenResponseError = AuthInvalidTokenResponseError; +/** + * Error thrown when email/password credentials are invalid. + * + * @example + * ```ts + * import { AuthInvalidCredentialsError } from '@supabase/auth-js' + * + * throw new AuthInvalidCredentialsError('Email or password is incorrect') + * ``` + */ class AuthInvalidCredentialsError extends CustomAuthError { constructor(message) { - super(message, 'AuthInvalidCredentialsError', 400); + super(message, 'AuthInvalidCredentialsError', 400, undefined); } } exports.AuthInvalidCredentialsError = AuthInvalidCredentialsError; +/** + * Error thrown when implicit grant redirects contain an error. + * + * @example + * ```ts + * import { AuthImplicitGrantRedirectError } from '@supabase/auth-js' + * + * throw new AuthImplicitGrantRedirectError('OAuth redirect failed', { + * error: 'access_denied', + * code: 'oauth_error', + * }) + * ``` + */ class AuthImplicitGrantRedirectError extends CustomAuthError { constructor(message, details = null) { - super(message, 'AuthImplicitGrantRedirectError', 500); + super(message, 'AuthImplicitGrantRedirectError', 500, undefined); this.details = null; this.details = details; } @@ -4857,9 +6428,22 @@ class AuthImplicitGrantRedirectError extends CustomAuthError { } } exports.AuthImplicitGrantRedirectError = AuthImplicitGrantRedirectError; +function isAuthImplicitGrantRedirectError(error) { + return isAuthError(error) && error.name === 'AuthImplicitGrantRedirectError'; +} +/** + * Error thrown during PKCE code exchanges. + * + * @example + * ```ts + * import { AuthPKCEGrantCodeExchangeError } from '@supabase/auth-js' + * + * throw new AuthPKCEGrantCodeExchangeError('PKCE exchange failed') + * ``` + */ class AuthPKCEGrantCodeExchangeError extends CustomAuthError { constructor(message, details = null) { - super(message, 'AuthPKCEGrantCodeExchangeError', 500); + super(message, 'AuthPKCEGrantCodeExchangeError', 500, undefined); this.details = null; this.details = details; } @@ -4873,43 +6457,116 @@ class AuthPKCEGrantCodeExchangeError extends CustomAuthError { } } exports.AuthPKCEGrantCodeExchangeError = AuthPKCEGrantCodeExchangeError; +/** + * Error thrown when the PKCE code verifier is not found in storage. + * This typically happens when the auth flow was initiated in a different + * browser, device, or the storage was cleared. + * + * @example + * ```ts + * import { AuthPKCECodeVerifierMissingError } from '@supabase/auth-js' + * + * throw new AuthPKCECodeVerifierMissingError() + * ``` + */ +class AuthPKCECodeVerifierMissingError extends CustomAuthError { + constructor() { + super('PKCE code verifier not found in storage. ' + + 'This can happen if the auth flow was initiated in a different browser or device, ' + + 'or if the storage was cleared. For SSR frameworks (Next.js, SvelteKit, etc.), ' + + 'use @supabase/ssr on both the server and client to store the code verifier in cookies.', 'AuthPKCECodeVerifierMissingError', 400, 'pkce_code_verifier_not_found'); + } +} +exports.AuthPKCECodeVerifierMissingError = AuthPKCECodeVerifierMissingError; +function isAuthPKCECodeVerifierMissingError(error) { + return isAuthError(error) && error.name === 'AuthPKCECodeVerifierMissingError'; +} +/** + * Error thrown when a transient fetch issue occurs. + * + * @example + * ```ts + * import { AuthRetryableFetchError } from '@supabase/auth-js' + * + * throw new AuthRetryableFetchError('Service temporarily unavailable', 503) + * ``` + */ class AuthRetryableFetchError extends CustomAuthError { constructor(message, status) { - super(message, 'AuthRetryableFetchError', status); + super(message, 'AuthRetryableFetchError', status, undefined); } } exports.AuthRetryableFetchError = AuthRetryableFetchError; function isAuthRetryableFetchError(error) { return isAuthError(error) && error.name === 'AuthRetryableFetchError'; } -exports.isAuthRetryableFetchError = isAuthRetryableFetchError; +/** + * This error is thrown on certain methods when the password used is deemed + * weak. Inspect the reasons to identify what password strength rules are + * inadequate. + */ +/** + * Error thrown when a supplied password is considered weak. + * + * @example + * ```ts + * import { AuthWeakPasswordError } from '@supabase/auth-js' + * + * throw new AuthWeakPasswordError('Password too short', 400, ['min_length']) + * ``` + */ +class AuthWeakPasswordError extends CustomAuthError { + constructor(message, status, reasons) { + super(message, 'AuthWeakPasswordError', status, 'weak_password'); + this.reasons = reasons; + } +} +exports.AuthWeakPasswordError = AuthWeakPasswordError; +function isAuthWeakPasswordError(error) { + return isAuthError(error) && error.name === 'AuthWeakPasswordError'; +} +/** + * Error thrown when a JWT cannot be verified or parsed. + * + * @example + * ```ts + * import { AuthInvalidJwtError } from '@supabase/auth-js' + * + * throw new AuthInvalidJwtError('Token signature is invalid') + * ``` + */ +class AuthInvalidJwtError extends CustomAuthError { + constructor(message) { + super(message, 'AuthInvalidJwtError', 400, 'invalid_jwt'); + } +} +exports.AuthInvalidJwtError = AuthInvalidJwtError; //# sourceMappingURL=errors.js.map /***/ }), -/***/ 202: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 7072: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -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; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports._noResolveJsonResponse = exports._generateLinkResponse = exports._ssoResponse = exports._userResponse = exports._sessionResponse = exports._request = void 0; -const helpers_1 = __nccwpck_require__(2846); -const errors_1 = __nccwpck_require__(6723); +exports.handleError = handleError; +exports._request = _request; +exports._sessionResponse = _sessionResponse; +exports._sessionResponsePassword = _sessionResponsePassword; +exports._userResponse = _userResponse; +exports._ssoResponse = _ssoResponse; +exports._generateLinkResponse = _generateLinkResponse; +exports._noResolveJsonResponse = _noResolveJsonResponse; +const tslib_1 = __nccwpck_require__(9808); +const constants_1 = __nccwpck_require__(518); +const helpers_1 = __nccwpck_require__(4044); +const errors_1 = __nccwpck_require__(9938); const _getErrorMessage = (err) => err.msg || err.message || err.error_description || err.error || JSON.stringify(err); const NETWORK_ERROR_CODES = [502, 503, 504]; async function handleError(error) { + var _a; if (!(0, helpers_1.looksLikeFetchResponse)(error)) { throw new errors_1.AuthRetryableFetchError(_getErrorMessage(error), 0); } @@ -4924,7 +6581,40 @@ async function handleError(error) { catch (e) { throw new errors_1.AuthUnknownError(_getErrorMessage(e), e); } - throw new errors_1.AuthApiError(_getErrorMessage(data), error.status || 500); + let errorCode = undefined; + const responseAPIVersion = (0, helpers_1.parseResponseAPIVersion)(error); + if (responseAPIVersion && + responseAPIVersion.getTime() >= constants_1.API_VERSIONS['2024-01-01'].timestamp && + typeof data === 'object' && + data && + typeof data.code === 'string') { + errorCode = data.code; + } + else if (typeof data === 'object' && data && typeof data.error_code === 'string') { + errorCode = data.error_code; + } + if (!errorCode) { + // Legacy support for weak password errors, when there were no error codes + if (typeof data === 'object' && + data && + typeof data.weak_password === 'object' && + data.weak_password && + Array.isArray(data.weak_password.reasons) && + data.weak_password.reasons.length && + data.weak_password.reasons.reduce((a, i) => a && typeof i === 'string', true)) { + throw new errors_1.AuthWeakPasswordError(_getErrorMessage(data), error.status, data.weak_password.reasons); + } + } + else if (errorCode === 'weak_password') { + throw new errors_1.AuthWeakPasswordError(_getErrorMessage(data), error.status, ((_a = data.weak_password) === null || _a === void 0 ? void 0 : _a.reasons) || []); + } + else if (errorCode === 'session_not_found') { + // The `session_id` inside the JWT does not correspond to a row in the + // `sessions` table. This usually means the user has signed out, has been + // deleted, or their session has somehow been terminated. + throw new errors_1.AuthSessionMissingError(); + } + throw new errors_1.AuthApiError(_getErrorMessage(data), error.status || 500, errorCode); } const _getRequestParams = (method, options, parameters, body) => { const params = { method, headers: (options === null || options === void 0 ? void 0 : options.headers) || {} }; @@ -4938,6 +6628,9 @@ const _getRequestParams = (method, options, parameters, body) => { async function _request(fetcher, method, url, options) { var _a; const headers = Object.assign({}, options === null || options === void 0 ? void 0 : options.headers); + if (!headers[constants_1.API_VERSION_HEADER_NAME]) { + headers[constants_1.API_VERSION_HEADER_NAME] = constants_1.API_VERSIONS['2024-01-01'].name; + } if (options === null || options === void 0 ? void 0 : options.jwt) { headers['Authorization'] = `Bearer ${options.jwt}`; } @@ -4946,15 +6639,17 @@ async function _request(fetcher, method, url, options) { qs['redirect_to'] = options.redirectTo; } const queryString = Object.keys(qs).length ? '?' + new URLSearchParams(qs).toString() : ''; - const data = await _handleRequest(fetcher, method, url + queryString, { headers, noResolveJson: options === null || options === void 0 ? void 0 : options.noResolveJson }, {}, options === null || options === void 0 ? void 0 : options.body); + const data = await _handleRequest(fetcher, method, url + queryString, { + headers, + noResolveJson: options === null || options === void 0 ? void 0 : options.noResolveJson, + }, {}, options === null || options === void 0 ? void 0 : options.body); return (options === null || options === void 0 ? void 0 : options.xform) ? options === null || options === void 0 ? void 0 : options.xform(data) : { data: Object.assign({}, data), error: null }; } -exports._request = _request; async function _handleRequest(fetcher, method, url, options, parameters, body) { const requestParams = _getRequestParams(method, options, parameters, body); let result; try { - result = await fetcher(url, requestParams); + result = await fetcher(url, Object.assign({}, requestParams)); } catch (e) { console.error(e); @@ -4986,19 +6681,30 @@ function _sessionResponse(data) { const user = (_a = data.user) !== null && _a !== void 0 ? _a : data; return { data: { session, user }, error: null }; } -exports._sessionResponse = _sessionResponse; +function _sessionResponsePassword(data) { + const response = _sessionResponse(data); + if (!response.error && + data.weak_password && + typeof data.weak_password === 'object' && + Array.isArray(data.weak_password.reasons) && + data.weak_password.reasons.length && + data.weak_password.message && + typeof data.weak_password.message === 'string' && + data.weak_password.reasons.reduce((a, i) => a && typeof i === 'string', true)) { + response.data.weak_password = data.weak_password; + } + return response; +} function _userResponse(data) { var _a; const user = (_a = data.user) !== null && _a !== void 0 ? _a : data; return { data: { user }, error: null }; } -exports._userResponse = _userResponse; function _ssoResponse(data) { return { data, error: null }; } -exports._ssoResponse = _ssoResponse; function _generateLinkResponse(data) { - const { action_link, email_otp, hashed_token, redirect_to, verification_type } = data, rest = __rest(data, ["action_link", "email_otp", "hashed_token", "redirect_to", "verification_type"]); + const { action_link, email_otp, hashed_token, redirect_to, verification_type } = data, rest = tslib_1.__rest(data, ["action_link", "email_otp", "hashed_token", "redirect_to", "verification_type"]); const properties = { action_link, email_otp, @@ -5015,11 +6721,9 @@ function _generateLinkResponse(data) { error: null, }; } -exports._generateLinkResponse = _generateLinkResponse; function _noResolveJsonResponse(data) { return data; } -exports._noResolveJsonResponse = _noResolveJsonResponse; /** * hasSession checks if the response object contains a valid session * @param data A response object @@ -5032,49 +6736,53 @@ function hasSession(data) { /***/ }), -/***/ 2846: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 4044: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.generatePKCEChallenge = exports.generatePKCEVerifier = exports.retryable = exports.sleep = exports.decodeJWTPayload = exports.Deferred = exports.decodeBase64URL = exports.removeItemAsync = exports.getItemAsync = exports.setItemAsync = exports.looksLikeFetchResponse = exports.resolveFetch = exports.parseParametersFromURL = exports.supportsLocalStorage = exports.isBrowser = exports.uuid = exports.expiresAt = void 0; +exports.Deferred = exports.removeItemAsync = exports.getItemAsync = exports.setItemAsync = exports.looksLikeFetchResponse = exports.resolveFetch = exports.supportsLocalStorage = exports.isBrowser = void 0; +exports.expiresAt = expiresAt; +exports.generateCallbackId = generateCallbackId; +exports.parseParametersFromURL = parseParametersFromURL; +exports.decodeJWT = decodeJWT; +exports.sleep = sleep; +exports.retryable = retryable; +exports.generatePKCEVerifier = generatePKCEVerifier; +exports.generatePKCEChallenge = generatePKCEChallenge; +exports.getCodeChallengeAndMethod = getCodeChallengeAndMethod; +exports.parseResponseAPIVersion = parseResponseAPIVersion; +exports.validateExp = validateExp; +exports.getAlgorithm = getAlgorithm; +exports.validateUUID = validateUUID; +exports.userNotAvailableProxy = userNotAvailableProxy; +exports.insecureUserWarningProxy = insecureUserWarningProxy; +exports.deepClone = deepClone; +const constants_1 = __nccwpck_require__(518); +const errors_1 = __nccwpck_require__(9938); +const base64url_1 = __nccwpck_require__(3649); function expiresAt(expiresIn) { const timeNow = Math.round(Date.now() / 1000); return timeNow + expiresIn; } -exports.expiresAt = expiresAt; -function uuid() { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - const r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8; - return v.toString(16); - }); +/** + * Generates a unique identifier for internal callback subscriptions. + * + * This function uses JavaScript Symbols to create guaranteed-unique identifiers + * for auth state change callbacks. Symbols are ideal for this use case because: + * - They are guaranteed unique by the JavaScript runtime + * - They work in all environments (browser, SSR, Node.js) + * - They avoid issues with Next.js 16 deterministic rendering requirements + * - They are perfect for internal, non-serializable identifiers + * + * Note: This function is only used for internal subscription management, + * not for security-critical operations like session tokens. + */ +function generateCallbackId() { + return Symbol('auth-callback'); } -exports.uuid = uuid; -const isBrowser = () => typeof document !== 'undefined'; +const isBrowser = () => typeof window !== 'undefined' && typeof document !== 'undefined'; exports.isBrowser = isBrowser; const localStorageWriteTests = { tested: false, @@ -5138,19 +6846,11 @@ function parseParametersFromURL(href) { }); return result; } -exports.parseParametersFromURL = parseParametersFromURL; const resolveFetch = (customFetch) => { - let _fetch; if (customFetch) { - _fetch = customFetch; - } - else if (typeof fetch === 'undefined') { - _fetch = (...args) => Promise.resolve().then(() => __importStar(__nccwpck_require__(2668))).then(({ default: fetch }) => fetch(...args)); + return (...args) => customFetch(...args); } - else { - _fetch = fetch; - } - return (...args) => _fetch(...args); + return (...args) => fetch(...args); }; exports.resolveFetch = resolveFetch; const looksLikeFetchResponse = (maybeResponse) => { @@ -5184,32 +6884,6 @@ const removeItemAsync = async (storage, key) => { await storage.removeItem(key); }; exports.removeItemAsync = removeItemAsync; -function decodeBase64URL(value) { - const key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - let base64 = ''; - let chr1, chr2, chr3; - let enc1, enc2, enc3, enc4; - let i = 0; - value = value.replace('-', '+').replace('_', '/'); - while (i < value.length) { - enc1 = key.indexOf(value.charAt(i++)); - enc2 = key.indexOf(value.charAt(i++)); - enc3 = key.indexOf(value.charAt(i++)); - enc4 = key.indexOf(value.charAt(i++)); - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - base64 = base64 + String.fromCharCode(chr1); - if (enc3 != 64 && chr2 != 0) { - base64 = base64 + String.fromCharCode(chr2); - } - if (enc4 != 64 && chr3 != 0) { - base64 = base64 + String.fromCharCode(chr3); - } - } - return base64; -} -exports.decodeBase64URL = decodeBase64URL; /** * A deferred represents some asynchronous work that is not yet finished, which * may or may not culminate in a value. @@ -5229,21 +6903,29 @@ class Deferred { } exports.Deferred = Deferred; Deferred.promiseConstructor = Promise; -// Taken from: https://stackoverflow.com/questions/38552003/how-to-decode-jwt-token-in-javascript-without-using-a-library -function decodeJWTPayload(token) { - // Regex checks for base64url format - const base64UrlRegex = /^([a-z0-9_-]{4})*($|[a-z0-9_-]{3}=?$|[a-z0-9_-]{2}(==)?$)$/i; +function decodeJWT(token) { const parts = token.split('.'); if (parts.length !== 3) { - throw new Error('JWT is not valid: not a JWT structure'); - } - if (!base64UrlRegex.test(parts[1])) { - throw new Error('JWT is not valid: payload is not in base64url format'); + throw new errors_1.AuthInvalidJwtError('Invalid JWT structure'); } - const base64Url = parts[1]; - return JSON.parse(decodeBase64URL(base64Url)); + // Regex checks for base64url format + for (let i = 0; i < parts.length; i++) { + if (!constants_1.BASE64URL_REGEX.test(parts[i])) { + throw new errors_1.AuthInvalidJwtError('JWT not in base64url format'); + } + } + const data = { + // using base64url lib + header: JSON.parse((0, base64url_1.stringFromBase64URL)(parts[0])), + payload: JSON.parse((0, base64url_1.stringFromBase64URL)(parts[1])), + signature: (0, base64url_1.base64UrlToUint8Array)(parts[2]), + raw: { + header: parts[0], + payload: parts[1], + }, + }; + return data; } -exports.decodeJWTPayload = decodeJWTPayload; /** * Creates a promise that resolves to null after some time. */ @@ -5252,7 +6934,6 @@ async function sleep(time) { setTimeout(() => accept(null), time); }); } -exports.sleep = sleep; /** * Converts the provided async function into a retryable function. Each result * or thrown error is sent to the isRetryable function which should return true @@ -5282,7 +6963,6 @@ function retryable(fn, isRetryable) { }); return promise; } -exports.retryable = retryable; function dec2hex(dec) { return ('0' + dec.toString(16)).substr(-2); } @@ -5302,7 +6982,6 @@ function generatePKCEVerifier() { crypto.getRandomValues(array); return Array.from(array, dec2hex).join(''); } -exports.generatePKCEVerifier = generatePKCEVerifier; async function sha256(randomString) { const encoder = new TextEncoder(); const encodedData = encoder.encode(randomString); @@ -5312,9 +6991,6 @@ async function sha256(randomString) { .map((c) => String.fromCharCode(c)) .join(''); } -function base64urlencode(str) { - return btoa(str).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); -} async function generatePKCEChallenge(verifier) { const hasCryptoSupport = typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined' && @@ -5324,44 +7000,151 @@ async function generatePKCEChallenge(verifier) { return verifier; } const hashed = await sha256(verifier); - return base64urlencode(hashed); + return btoa(hashed).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); +} +async function getCodeChallengeAndMethod(storage, storageKey, isPasswordRecovery = false) { + const codeVerifier = generatePKCEVerifier(); + let storedCodeVerifier = codeVerifier; + if (isPasswordRecovery) { + storedCodeVerifier += '/PASSWORD_RECOVERY'; + } + await (0, exports.setItemAsync)(storage, `${storageKey}-code-verifier`, storedCodeVerifier); + const codeChallenge = await generatePKCEChallenge(codeVerifier); + const codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256'; + return [codeChallenge, codeChallengeMethod]; +} +/** Parses the API version which is 2YYY-MM-DD. */ +const API_VERSION_REGEX = /^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[0-1])$/i; +function parseResponseAPIVersion(response) { + const apiVersion = response.headers.get(constants_1.API_VERSION_HEADER_NAME); + if (!apiVersion) { + return null; + } + if (!apiVersion.match(API_VERSION_REGEX)) { + return null; + } + try { + const date = new Date(`${apiVersion}T00:00:00.0Z`); + return date; + } + catch (e) { + return null; + } +} +function validateExp(exp) { + if (!exp) { + throw new Error('Missing exp claim'); + } + const timeNow = Math.floor(Date.now() / 1000); + if (exp <= timeNow) { + throw new Error('JWT has expired'); + } +} +function getAlgorithm(alg) { + switch (alg) { + case 'RS256': + return { + name: 'RSASSA-PKCS1-v1_5', + hash: { name: 'SHA-256' }, + }; + case 'ES256': + return { + name: 'ECDSA', + namedCurve: 'P-256', + hash: { name: 'SHA-256' }, + }; + default: + throw new Error('Invalid alg claim'); + } +} +const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/; +function validateUUID(str) { + if (!UUID_REGEX.test(str)) { + throw new Error('@supabase/auth-js: Expected parameter to be UUID but is not'); + } +} +function userNotAvailableProxy() { + const proxyTarget = {}; + return new Proxy(proxyTarget, { + get: (target, prop) => { + if (prop === '__isUserNotAvailableProxy') { + return true; + } + // Preventative check for common problematic symbols during cloning/inspection + // These symbols might be accessed by structuredClone or other internal mechanisms. + if (typeof prop === 'symbol') { + const sProp = prop.toString(); + if (sProp === 'Symbol(Symbol.toPrimitive)' || + sProp === 'Symbol(Symbol.toStringTag)' || + sProp === 'Symbol(util.inspect.custom)') { + // Node.js util.inspect + return undefined; + } + } + throw new Error(`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Accessing the "${prop}" property of the session object is not supported. Please use getUser() instead.`); + }, + set: (_target, prop) => { + throw new Error(`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Setting the "${prop}" property of the session object is not supported. Please use getUser() to fetch a user object you can manipulate.`); + }, + deleteProperty: (_target, prop) => { + throw new Error(`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Deleting the "${prop}" property of the session object is not supported. Please use getUser() to fetch a user object you can manipulate.`); + }, + }); +} +/** + * Creates a proxy around a user object that warns when properties are accessed on the server. + * This is used to alert developers that using user data from getSession() on the server is insecure. + * + * @param user The actual user object to wrap + * @param suppressWarningRef An object with a 'value' property that controls warning suppression + * @returns A proxied user object that warns on property access + */ +function insecureUserWarningProxy(user, suppressWarningRef) { + return new Proxy(user, { + get: (target, prop, receiver) => { + // Allow internal checks without warning + if (prop === '__isInsecureUserWarningProxy') { + return true; + } + // Preventative check for common problematic symbols during cloning/inspection + // These symbols might be accessed by structuredClone or other internal mechanisms + if (typeof prop === 'symbol') { + const sProp = prop.toString(); + if (sProp === 'Symbol(Symbol.toPrimitive)' || + sProp === 'Symbol(Symbol.toStringTag)' || + sProp === 'Symbol(util.inspect.custom)' || + sProp === 'Symbol(nodejs.util.inspect.custom)') { + // Return the actual value for these symbols to allow proper inspection + return Reflect.get(target, prop, receiver); + } + } + // Emit warning on first property access + if (!suppressWarningRef.value && typeof prop === 'string') { + console.warn('Using the user object as returned from supabase.auth.getSession() or from some supabase.auth.onAuthStateChange() events could be insecure! This value comes directly from the storage medium (usually cookies on the server) and may not be authentic. Use supabase.auth.getUser() instead which authenticates the data by contacting the Supabase Auth server.'); + suppressWarningRef.value = true; + } + return Reflect.get(target, prop, receiver); + }, + }); +} +/** + * Deep clones a JSON-serializable object using JSON.parse(JSON.stringify(obj)). + * Note: Only works for JSON-safe data. + */ +function deepClone(obj) { + return JSON.parse(JSON.stringify(obj)); } -exports.generatePKCEChallenge = generatePKCEChallenge; //# sourceMappingURL=helpers.js.map /***/ }), -/***/ 9766: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 1479: +/***/ ((__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.memoryLocalStorageAdapter = exports.localStorageAdapter = void 0; -const helpers_1 = __nccwpck_require__(2846); -/** - * Provides safe access to the globalThis.localStorage property. - */ -exports.localStorageAdapter = { - getItem: (key) => { - if (!(0, helpers_1.supportsLocalStorage)()) { - return null; - } - return globalThis.localStorage.getItem(key); - }, - setItem: (key, value) => { - if (!(0, helpers_1.supportsLocalStorage)()) { - return; - } - globalThis.localStorage.setItem(key, value); - }, - removeItem: (key) => { - if (!(0, helpers_1.supportsLocalStorage)()) { - return; - } - globalThis.localStorage.removeItem(key); - }, -}; +exports.memoryLocalStorageAdapter = memoryLocalStorageAdapter; /** * Returns a localStorage-like object that stores the key-value pairs in * memory. @@ -5379,19 +7162,20 @@ function memoryLocalStorageAdapter(store = {}) { }, }; } -exports.memoryLocalStorageAdapter = memoryLocalStorageAdapter; //# sourceMappingURL=local-storage.js.map /***/ }), -/***/ 7000: +/***/ 163: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.navigatorLock = exports.NavigatorLockAcquireTimeoutError = exports.LockAcquireTimeoutError = exports.internals = void 0; -const helpers_1 = __nccwpck_require__(2846); +exports.ProcessLockAcquireTimeoutError = exports.NavigatorLockAcquireTimeoutError = exports.LockAcquireTimeoutError = exports.internals = void 0; +exports.navigatorLock = navigatorLock; +exports.processLock = processLock; +const helpers_1 = __nccwpck_require__(4044); /** * @experimental */ @@ -5404,6 +7188,22 @@ exports.internals = { globalThis.localStorage && globalThis.localStorage.getItem('supabase.gotrue-js.locks.debug') === 'true'), }; +/** + * An error thrown when a lock cannot be acquired after some amount of time. + * + * Use the {@link #isAcquireTimeout} property instead of checking with `instanceof`. + * + * @example + * ```ts + * import { LockAcquireTimeoutError } from '@supabase/auth-js' + * + * class CustomLockError extends LockAcquireTimeoutError { + * constructor() { + * super('Lock timed out') + * } + * } + * ``` + */ class LockAcquireTimeoutError extends Error { constructor(message) { super(message); @@ -5411,9 +7211,32 @@ class LockAcquireTimeoutError extends Error { } } exports.LockAcquireTimeoutError = LockAcquireTimeoutError; +/** + * Error thrown when the browser Navigator Lock API fails to acquire a lock. + * + * @example + * ```ts + * import { NavigatorLockAcquireTimeoutError } from '@supabase/auth-js' + * + * throw new NavigatorLockAcquireTimeoutError('Lock timed out') + * ``` + */ class NavigatorLockAcquireTimeoutError extends LockAcquireTimeoutError { } exports.NavigatorLockAcquireTimeoutError = NavigatorLockAcquireTimeoutError; +/** + * Error thrown when the process-level lock helper cannot acquire a lock. + * + * @example + * ```ts + * import { ProcessLockAcquireTimeoutError } from '@supabase/auth-js' + * + * throw new ProcessLockAcquireTimeoutError('Lock timed out') + * ``` + */ +class ProcessLockAcquireTimeoutError extends LockAcquireTimeoutError { +} +exports.ProcessLockAcquireTimeoutError = ProcessLockAcquireTimeoutError; /** * Implements a global exclusive lock using the Navigator LockManager API. It * is available on all browsers released after 2022-03-15 with Safari being the @@ -5432,14 +7255,18 @@ exports.NavigatorLockAcquireTimeoutError = NavigatorLockAcquireTimeoutError; * function. The lock waits for that promise to finish (with or without error), * while the function will finally wait for the result anyway. * - * @experimental - * * @param name Name of the lock to be acquired. * @param acquireTimeout If negative, no timeout. If 0 an error is thrown if * the lock can't be acquired without waiting. If positive, the lock acquire * will time out after so many milliseconds. An error is * a timeout if it has `isAcquireTimeout` set to true. * @param fn The operation to run once the lock is acquired. + * @example + * ```ts + * await navigatorLock('sync-user', 1000, async () => { + * await refreshSession() + * }) + * ``` */ async function navigatorLock(name, acquireTimeout, fn) { if (exports.internals.debug) { @@ -5455,67 +7282,218 @@ async function navigatorLock(name, acquireTimeout, fn) { }, acquireTimeout); } // MDN article: https://developer.mozilla.org/en-US/docs/Web/API/LockManager/request - return await globalThis.navigator.locks.request(name, acquireTimeout === 0 - ? { - mode: 'exclusive', - ifAvailable: true, - } - : { - mode: 'exclusive', - signal: abortController.signal, - }, async (lock) => { - if (lock) { - if (exports.internals.debug) { - console.log('@supabase/gotrue-js: navigatorLock: acquired', name, lock.name); - } - try { - return await fn(); - } - finally { + // Wrapping navigator.locks.request() with a plain Promise is done as some + // libraries like zone.js patch the Promise object to track the execution + // context. However, it appears that most browsers use an internal promise + // implementation when using the navigator.locks.request() API causing them + // to lose context and emit confusing log messages or break certain features. + // This wrapping is believed to help zone.js track the execution context + // better. + await Promise.resolve(); + try { + return await globalThis.navigator.locks.request(name, acquireTimeout === 0 + ? { + mode: 'exclusive', + ifAvailable: true, + } + : { + mode: 'exclusive', + signal: abortController.signal, + }, async (lock) => { + if (lock) { if (exports.internals.debug) { - console.log('@supabase/gotrue-js: navigatorLock: released', name, lock.name); + console.log('@supabase/gotrue-js: navigatorLock: acquired', name, lock.name); } - } - } - else { - if (acquireTimeout === 0) { - if (exports.internals.debug) { - console.log('@supabase/gotrue-js: navigatorLock: not immediately available', name); + try { + return await fn(); + } + finally { + if (exports.internals.debug) { + console.log('@supabase/gotrue-js: navigatorLock: released', name, lock.name); + } } - throw new NavigatorLockAcquireTimeoutError(`Acquiring an exclusive Navigator LockManager lock "${name}" immediately failed`); } else { - if (exports.internals.debug) { + if (acquireTimeout === 0) { + if (exports.internals.debug) { + console.log('@supabase/gotrue-js: navigatorLock: not immediately available', name); + } + throw new NavigatorLockAcquireTimeoutError(`Acquiring an exclusive Navigator LockManager lock "${name}" immediately failed`); + } + else { + if (exports.internals.debug) { + try { + const result = await globalThis.navigator.locks.query(); + console.log('@supabase/gotrue-js: Navigator LockManager state', JSON.stringify(result, null, ' ')); + } + catch (e) { + console.warn('@supabase/gotrue-js: Error when querying Navigator LockManager state', e); + } + } + // Browser is not following the Navigator LockManager spec, it + // returned a null lock when we didn't use ifAvailable. So we can + // pretend the lock is acquired in the name of backward compatibility + // and user experience and just run the function. + console.warn('@supabase/gotrue-js: Navigator LockManager returned a null lock when using #request without ifAvailable set to true, it appears this browser is not following the LockManager spec https://developer.mozilla.org/en-US/docs/Web/API/LockManager/request'); + return await fn(); + } + } + }); + } + catch (e) { + if ((e === null || e === void 0 ? void 0 : e.name) === 'AbortError' && acquireTimeout > 0) { + // The lock acquisition was aborted because the timeout fired while the + // request was still pending. This typically means another lock holder is + // not releasing the lock, possibly due to React Strict Mode's + // double-mount/unmount behavior or a component unmounting mid-operation, + // leaving an orphaned lock. + // + // Recovery: use { steal: true } to forcefully acquire the lock. Per the + // Web Locks API spec, this releases any currently held lock with the same + // name and grants the request immediately, preempting any queued requests. + // The previous holder's callback continues running to completion but no + // longer holds the lock for exclusion purposes. + // + // See: https://github.com/supabase/supabase/issues/42505 + if (exports.internals.debug) { + console.log('@supabase/gotrue-js: navigatorLock: acquire timeout, recovering by stealing lock', name); + } + console.warn(`@supabase/gotrue-js: Lock "${name}" was not released within ${acquireTimeout}ms. ` + + 'This may indicate an orphaned lock from a component unmount (e.g., React Strict Mode). ' + + 'Forcefully acquiring the lock to recover.'); + return await Promise.resolve().then(() => globalThis.navigator.locks.request(name, { + mode: 'exclusive', + steal: true, + }, async (lock) => { + if (lock) { + if (exports.internals.debug) { + console.log('@supabase/gotrue-js: navigatorLock: recovered (stolen)', name, lock.name); + } try { - const result = await globalThis.navigator.locks.query(); - console.log('@supabase/gotrue-js: Navigator LockManager state', JSON.stringify(result, null, ' ')); + return await fn(); } - catch (e) { - console.warn('@supabase/gotrue-js: Error when querying Navigator LockManager state', e); + finally { + if (exports.internals.debug) { + console.log('@supabase/gotrue-js: navigatorLock: released (stolen)', name, lock.name); + } } } - // Browser is not following the Navigator LockManager spec, it - // returned a null lock when we didn't use ifAvailable. So we can - // pretend the lock is acquired in the name of backward compatibility - // and user experience and just run the function. - console.warn('@supabase/gotrue-js: Navigator LockManager returned a null lock when using #request without ifAvailable set to true, it appears this browser is not following the LockManager spec https://developer.mozilla.org/en-US/docs/Web/API/LockManager/request'); - return await fn(); + else { + // This should not happen with steal: true, but handle gracefully. + console.warn('@supabase/gotrue-js: Navigator LockManager returned null lock even with steal: true'); + return await fn(); + } + })); + } + throw e; + } +} +const PROCESS_LOCKS = {}; +/** + * Implements a global exclusive lock that works only in the current process. + * Useful for environments like React Native or other non-browser + * single-process (i.e. no concept of "tabs") environments. + * + * Use {@link #navigatorLock} in browser environments. + * + * @param name Name of the lock to be acquired. + * @param acquireTimeout If negative, no timeout. If 0 an error is thrown if + * the lock can't be acquired without waiting. If positive, the lock acquire + * will time out after so many milliseconds. An error is + * a timeout if it has `isAcquireTimeout` set to true. + * @param fn The operation to run once the lock is acquired. + * @example + * ```ts + * await processLock('migrate', 5000, async () => { + * await runMigration() + * }) + * ``` + */ +async function processLock(name, acquireTimeout, fn) { + var _a; + const previousOperation = (_a = PROCESS_LOCKS[name]) !== null && _a !== void 0 ? _a : Promise.resolve(); + // Wrap previousOperation to handle errors without using .catch() + // This avoids Firefox content script security errors + const previousOperationHandled = (async () => { + try { + await previousOperation; + return null; + } + catch (e) { + // ignore error of previous operation that we're waiting to finish + return null; + } + })(); + const currentOperation = (async () => { + let timeoutId = null; + try { + // Wait for either previous operation or timeout + const timeoutPromise = acquireTimeout >= 0 + ? new Promise((_, reject) => { + timeoutId = setTimeout(() => { + console.warn(`@supabase/gotrue-js: Lock "${name}" acquisition timed out after ${acquireTimeout}ms. ` + + 'This may be caused by another operation holding the lock. ' + + 'Consider increasing lockAcquireTimeout or checking for stuck operations.'); + reject(new ProcessLockAcquireTimeoutError(`Acquiring process lock with name "${name}" timed out`)); + }, acquireTimeout); + }) + : null; + await Promise.race([previousOperationHandled, timeoutPromise].filter((x) => x)); + // If we reach here, previousOperationHandled won the race + // Clear the timeout to prevent false warnings + if (timeoutId !== null) { + clearTimeout(timeoutId); + } + } + catch (e) { + // Clear the timeout on error path as well + if (timeoutId !== null) { + clearTimeout(timeoutId); + } + // Re-throw timeout errors, ignore others + if (e && e.isAcquireTimeout) { + throw e; + } + // Fall through to run fn() - previous operation finished with error + } + // Previous operations finished and we didn't get a race on the acquire + // timeout, so the current operation can finally start + return await fn(); + })(); + PROCESS_LOCKS[name] = (async () => { + try { + return await currentOperation; + } + catch (e) { + if (e && e.isAcquireTimeout) { + // if the current operation timed out, it doesn't mean that the previous + // operation finished, so we need continue waiting for it to finish + try { + await previousOperation; + } + catch (prevError) { + // Ignore previous operation errors + } + return null; } + throw e; } - }); + })(); + // finally wait for the current operation to finish successfully, with an + // error or with an acquire timeout error + return await currentOperation; } -exports.navigatorLock = navigatorLock; //# sourceMappingURL=locks.js.map /***/ }), -/***/ 5568: +/***/ 1897: /***/ ((__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.polyfillGlobalThis = void 0; +exports.polyfillGlobalThis = polyfillGlobalThis; /** * https://mathiasbynens.be/notes/globalthis */ @@ -5541,13998 +7519,13944 @@ function polyfillGlobalThis() { } } } -exports.polyfillGlobalThis = polyfillGlobalThis; //# sourceMappingURL=polyfills.js.map /***/ }), -/***/ 5739: +/***/ 1852: /***/ ((__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.SIGN_OUT_SCOPES = void 0; +const WeakPasswordReasons = (/* unused pure expression or super */ null && (['length', 'characters', 'pwned'])); +const AMRMethods = (/* unused pure expression or super */ null && ([ + 'password', + 'otp', + 'oauth', + 'totp', + 'mfa/totp', + 'mfa/phone', + 'mfa/webauthn', + 'anonymous', + 'sso/saml', + 'magiclink', + 'web3', + 'oauth_provider/authorization_code', +])); +const FactorTypes = (/* unused pure expression or super */ null && (['totp', 'phone', 'webauthn'])); +const FactorVerificationStatuses = (/* unused pure expression or super */ null && (['verified', 'unverified'])); +const MFATOTPChannels = (/* unused pure expression or super */ null && (['sms', 'whatsapp'])); +exports.SIGN_OUT_SCOPES = ['global', 'local', 'others']; //# sourceMappingURL=types.js.map /***/ }), -/***/ 5910: +/***/ 6677: /***/ ((__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.version = void 0; -// Generated by genversion. -exports.version = '2.57.0'; +// Generated automatically during releases by scripts/update-version-files.ts +// This file provides runtime access to the package version for: +// - HTTP request headers (e.g., X-Client-Info header for API requests) +// - Debugging and support (identifying which version is running) +// - Telemetry and logging (version reporting in errors/analytics) +// - Ensuring build artifacts match the published package version +exports.version = '2.99.0'; //# sourceMappingURL=version.js.map /***/ }), -/***/ 2668: -/***/ ((module, exports, __nccwpck_require__) => { +/***/ 9031: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - +// types and functions copied over from viem so this library doesn't depend on it Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getAddress = getAddress; +exports.fromHex = fromHex; +exports.toHex = toHex; +exports.createSiweMessage = createSiweMessage; +function getAddress(address) { + if (!/^0x[a-fA-F0-9]{40}$/.test(address)) { + throw new Error(`@supabase/auth-js: Address "${address}" is invalid.`); + } + return address.toLowerCase(); +} +function fromHex(hex) { + return parseInt(hex, 16); +} +function toHex(value) { + const bytes = new TextEncoder().encode(value); + const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join(''); + return ('0x' + hex); +} +/** + * Creates EIP-4361 formatted message. + */ +function createSiweMessage(parameters) { + var _a; + const { chainId, domain, expirationTime, issuedAt = new Date(), nonce, notBefore, requestId, resources, scheme, uri, version, } = parameters; + // Validate fields + { + if (!Number.isInteger(chainId)) + throw new Error(`@supabase/auth-js: Invalid SIWE message field "chainId". Chain ID must be a EIP-155 chain ID. Provided value: ${chainId}`); + if (!domain) + throw new Error(`@supabase/auth-js: Invalid SIWE message field "domain". Domain must be provided.`); + if (nonce && nonce.length < 8) + throw new Error(`@supabase/auth-js: Invalid SIWE message field "nonce". Nonce must be at least 8 characters. Provided value: ${nonce}`); + if (!uri) + throw new Error(`@supabase/auth-js: Invalid SIWE message field "uri". URI must be provided.`); + if (version !== '1') + throw new Error(`@supabase/auth-js: Invalid SIWE message field "version". Version must be '1'. Provided value: ${version}`); + if ((_a = parameters.statement) === null || _a === void 0 ? void 0 : _a.includes('\n')) + throw new Error(`@supabase/auth-js: Invalid SIWE message field "statement". Statement must not include '\\n'. Provided value: ${parameters.statement}`); + } + // Construct message + const address = getAddress(parameters.address); + const origin = scheme ? `${scheme}://${domain}` : domain; + const statement = parameters.statement ? `${parameters.statement}\n` : ''; + const prefix = `${origin} wants you to sign in with your Ethereum account:\n${address}\n\n${statement}`; + let suffix = `URI: ${uri}\nVersion: ${version}\nChain ID: ${chainId}${nonce ? `\nNonce: ${nonce}` : ''}\nIssued At: ${issuedAt.toISOString()}`; + if (expirationTime) + suffix += `\nExpiration Time: ${expirationTime.toISOString()}`; + if (notBefore) + suffix += `\nNot Before: ${notBefore.toISOString()}`; + if (requestId) + suffix += `\nRequest ID: ${requestId}`; + if (resources) { + let content = '\nResources:'; + for (const resource of resources) { + if (!resource || typeof resource !== 'string') + throw new Error(`@supabase/auth-js: Invalid SIWE message field "resources". Every resource must be a valid string. Provided value: ${resource}`); + content += `\n- ${resource}`; + } + suffix += content; + } + return `${prefix}\n${suffix}`; +} +//# sourceMappingURL=ethereum.js.map -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var Stream = _interopDefault(__nccwpck_require__(2781)); -var http = _interopDefault(__nccwpck_require__(3685)); -var Url = _interopDefault(__nccwpck_require__(7310)); -var whatwgUrl = _interopDefault(__nccwpck_require__(8665)); -var https = _interopDefault(__nccwpck_require__(5687)); -var zlib = _interopDefault(__nccwpck_require__(9796)); - -// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js - -// fix for "Readable" isn't a named export issue -const Readable = Stream.Readable; - -const BUFFER = Symbol('buffer'); -const TYPE = Symbol('type'); - -class Blob { - constructor() { - this[TYPE] = ''; - - const blobParts = arguments[0]; - const options = arguments[1]; - - const buffers = []; - let size = 0; - - if (blobParts) { - const a = blobParts; - const length = Number(a.length); - for (let i = 0; i < length; i++) { - const element = a[i]; - let buffer; - if (element instanceof Buffer) { - buffer = element; - } else if (ArrayBuffer.isView(element)) { - buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); - } else if (element instanceof ArrayBuffer) { - buffer = Buffer.from(element); - } else if (element instanceof Blob) { - buffer = element[BUFFER]; - } else { - buffer = Buffer.from(typeof element === 'string' ? element : String(element)); - } - size += buffer.length; - buffers.push(buffer); - } - } +/***/ }), - this[BUFFER] = Buffer.concat(buffers); +/***/ 7906: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - let type = options && options.type !== undefined && String(options.type).toLowerCase(); - if (type && !/[^\u0020-\u007E]/.test(type)) { - this[TYPE] = type; - } - } - get size() { - return this[BUFFER].length; - } - get type() { - return this[TYPE]; - } - text() { - return Promise.resolve(this[BUFFER].toString()); - } - arrayBuffer() { - const buf = this[BUFFER]; - const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); - return Promise.resolve(ab); - } - stream() { - const readable = new Readable(); - readable._read = function () {}; - readable.push(this[BUFFER]); - readable.push(null); - return readable; - } - toString() { - return '[object Blob]'; - } - slice() { - const size = this.size; - - const start = arguments[0]; - const end = arguments[1]; - let relativeStart, relativeEnd; - if (start === undefined) { - relativeStart = 0; - } else if (start < 0) { - relativeStart = Math.max(size + start, 0); - } else { - relativeStart = Math.min(start, size); - } - if (end === undefined) { - relativeEnd = size; - } else if (end < 0) { - relativeEnd = Math.max(size + end, 0); - } else { - relativeEnd = Math.min(end, size); - } - const span = Math.max(relativeEnd - relativeStart, 0); +"use strict"; - const buffer = this[BUFFER]; - const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); - const blob = new Blob([], { type: arguments[2] }); - blob[BUFFER] = slicedBuffer; - return blob; - } +/* eslint-disable @typescript-eslint/ban-ts-comment */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.WebAuthnUnknownError = exports.WebAuthnError = void 0; +exports.isWebAuthnError = isWebAuthnError; +exports.identifyRegistrationError = identifyRegistrationError; +exports.identifyAuthenticationError = identifyAuthenticationError; +const webauthn_1 = __nccwpck_require__(9451); +/** + * A custom Error used to return a more nuanced error detailing _why_ one of the eight documented + * errors in the spec was raised after calling `navigator.credentials.create()` or + * `navigator.credentials.get()`: + * + * - `AbortError` + * - `ConstraintError` + * - `InvalidStateError` + * - `NotAllowedError` + * - `NotSupportedError` + * - `SecurityError` + * - `TypeError` + * - `UnknownError` + * + * Error messages were determined through investigation of the spec to determine under which + * scenarios a given error would be raised. + */ +class WebAuthnError extends Error { + constructor({ message, code, cause, name, }) { + var _a; + // @ts-ignore: help Rollup understand that `cause` is okay to set + super(message, { cause }); + this.__isWebAuthnError = true; + this.name = (_a = name !== null && name !== void 0 ? name : (cause instanceof Error ? cause.name : undefined)) !== null && _a !== void 0 ? _a : 'Unknown Error'; + this.code = code; + } } - -Object.defineProperties(Blob.prototype, { - size: { enumerable: true }, - type: { enumerable: true }, - slice: { enumerable: true } -}); - -Object.defineProperty(Blob.prototype, Symbol.toStringTag, { - value: 'Blob', - writable: false, - enumerable: false, - configurable: true -}); - +exports.WebAuthnError = WebAuthnError; /** - * fetch-error.js - * - * FetchError interface for operational errors + * Error class for unknown WebAuthn errors. + * Wraps unexpected errors that don't match known WebAuthn error conditions. */ - +class WebAuthnUnknownError extends WebAuthnError { + constructor(message, originalError) { + super({ + code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY', + cause: originalError, + message, + }); + this.name = 'WebAuthnUnknownError'; + this.originalError = originalError; + } +} +exports.WebAuthnUnknownError = WebAuthnUnknownError; /** - * Create FetchError instance - * - * @param String message Error message for human - * @param String type Error type for machine - * @param String systemError For Node.js system error - * @return FetchError + * Type guard to check if an error is a WebAuthnError. + * @param {unknown} error - The error to check + * @returns {boolean} True if the error is a WebAuthnError */ -function FetchError(message, type, systemError) { - Error.call(this, message); - - this.message = message; - this.type = type; - - // when err.type is `system`, err.code contains system error code - if (systemError) { - this.code = this.errno = systemError.code; - } - - // hide custom error implementation details from end-users - Error.captureStackTrace(this, this.constructor); +function isWebAuthnError(error) { + return typeof error === 'object' && error !== null && '__isWebAuthnError' in error; } - -FetchError.prototype = Object.create(Error.prototype); -FetchError.prototype.constructor = FetchError; -FetchError.prototype.name = 'FetchError'; - -let convert; - -const INTERNALS = Symbol('Body internals'); - -// fix an issue where "PassThrough" isn't a named export for node <10 -const PassThrough = Stream.PassThrough; - /** - * Body mixin - * - * Ref: https://fetch.spec.whatwg.org/#body - * - * @param Stream body Readable stream - * @param Object opts Response options - * @return Void + * Attempt to intuit _why_ an error was raised after calling `navigator.credentials.create()`. + * Maps browser errors to specific WebAuthn error codes for better debugging. + * @param {Object} params - Error identification parameters + * @param {Error} params.error - The error thrown by the browser + * @param {CredentialCreationOptions} params.options - The options passed to credentials.create() + * @returns {WebAuthnError} A WebAuthnError with a specific error code + * @see {@link https://w3c.github.io/webauthn/#sctn-createCredential W3C WebAuthn Spec - Create Credential} */ -function Body(body) { - var _this = this; - - var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, - _ref$size = _ref.size; - - let size = _ref$size === undefined ? 0 : _ref$size; - var _ref$timeout = _ref.timeout; - let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; - - if (body == null) { - // body is undefined or null - body = null; - } else if (isURLSearchParams(body)) { - // body is a URLSearchParams - body = Buffer.from(body.toString()); - } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { - // body is ArrayBuffer - body = Buffer.from(body); - } else if (ArrayBuffer.isView(body)) { - // body is ArrayBufferView - body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); - } else if (body instanceof Stream) ; else { - // none of the above - // coerce to string then buffer - body = Buffer.from(String(body)); - } - this[INTERNALS] = { - body, - disturbed: false, - error: null - }; - this.size = size; - this.timeout = timeout; - - if (body instanceof Stream) { - body.on('error', function (err) { - const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); - _this[INTERNALS].error = error; - }); - } +function identifyRegistrationError({ error, options, }) { + var _a, _b, _c; + const { publicKey } = options; + if (!publicKey) { + throw Error('options was missing required publicKey property'); + } + if (error.name === 'AbortError') { + if (options.signal instanceof AbortSignal) { + // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 16) + return new WebAuthnError({ + message: 'Registration ceremony was sent an abort signal', + code: 'ERROR_CEREMONY_ABORTED', + cause: error, + }); + } + } + else if (error.name === 'ConstraintError') { + if (((_a = publicKey.authenticatorSelection) === null || _a === void 0 ? void 0 : _a.requireResidentKey) === true) { + // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 4) + return new WebAuthnError({ + message: 'Discoverable credentials were required but no available authenticator supported it', + code: 'ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT', + cause: error, + }); + } + else if ( + // @ts-ignore: `mediation` doesn't yet exist on CredentialCreationOptions but it's possible as of Sept 2024 + options.mediation === 'conditional' && + ((_b = publicKey.authenticatorSelection) === null || _b === void 0 ? void 0 : _b.userVerification) === 'required') { + // https://w3c.github.io/webauthn/#sctn-createCredential (Step 22.4) + return new WebAuthnError({ + message: 'User verification was required during automatic registration but it could not be performed', + code: 'ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE', + cause: error, + }); + } + else if (((_c = publicKey.authenticatorSelection) === null || _c === void 0 ? void 0 : _c.userVerification) === 'required') { + // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 5) + return new WebAuthnError({ + message: 'User verification was required but no available authenticator supported it', + code: 'ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT', + cause: error, + }); + } + } + else if (error.name === 'InvalidStateError') { + // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 20) + // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 3) + return new WebAuthnError({ + message: 'The authenticator was previously registered', + code: 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED', + cause: error, + }); + } + else if (error.name === 'NotAllowedError') { + /** + * Pass the error directly through. Platforms are overloading this error beyond what the spec + * defines and we don't want to overwrite potentially useful error messages. + */ + return new WebAuthnError({ + message: error.message, + code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY', + cause: error, + }); + } + else if (error.name === 'NotSupportedError') { + const validPubKeyCredParams = publicKey.pubKeyCredParams.filter((param) => param.type === 'public-key'); + if (validPubKeyCredParams.length === 0) { + // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 10) + return new WebAuthnError({ + message: 'No entry in pubKeyCredParams was of type "public-key"', + code: 'ERROR_MALFORMED_PUBKEYCREDPARAMS', + cause: error, + }); + } + // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 2) + return new WebAuthnError({ + message: 'No available authenticator supported any of the specified pubKeyCredParams algorithms', + code: 'ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG', + cause: error, + }); + } + else if (error.name === 'SecurityError') { + const effectiveDomain = window.location.hostname; + if (!(0, webauthn_1.isValidDomain)(effectiveDomain)) { + // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 7) + return new WebAuthnError({ + message: `${window.location.hostname} is an invalid domain`, + code: 'ERROR_INVALID_DOMAIN', + cause: error, + }); + } + else if (publicKey.rp.id !== effectiveDomain) { + // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 8) + return new WebAuthnError({ + message: `The RP ID "${publicKey.rp.id}" is invalid for this domain`, + code: 'ERROR_INVALID_RP_ID', + cause: error, + }); + } + } + else if (error.name === 'TypeError') { + if (publicKey.user.id.byteLength < 1 || publicKey.user.id.byteLength > 64) { + // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 5) + return new WebAuthnError({ + message: 'User ID was not between 1 and 64 characters', + code: 'ERROR_INVALID_USER_ID_LENGTH', + cause: error, + }); + } + } + else if (error.name === 'UnknownError') { + // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 1) + // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 8) + return new WebAuthnError({ + message: 'The authenticator was unable to process the specified options, or could not create a new credential', + code: 'ERROR_AUTHENTICATOR_GENERAL_ERROR', + cause: error, + }); + } + return new WebAuthnError({ + message: 'a Non-Webauthn related error has occurred', + code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY', + cause: error, + }); } +/** + * Attempt to intuit _why_ an error was raised after calling `navigator.credentials.get()`. + * Maps browser errors to specific WebAuthn error codes for better debugging. + * @param {Object} params - Error identification parameters + * @param {Error} params.error - The error thrown by the browser + * @param {CredentialRequestOptions} params.options - The options passed to credentials.get() + * @returns {WebAuthnError} A WebAuthnError with a specific error code + * @see {@link https://w3c.github.io/webauthn/#sctn-getAssertion W3C WebAuthn Spec - Get Assertion} + */ +function identifyAuthenticationError({ error, options, }) { + const { publicKey } = options; + if (!publicKey) { + throw Error('options was missing required publicKey property'); + } + if (error.name === 'AbortError') { + if (options.signal instanceof AbortSignal) { + // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 16) + return new WebAuthnError({ + message: 'Authentication ceremony was sent an abort signal', + code: 'ERROR_CEREMONY_ABORTED', + cause: error, + }); + } + } + else if (error.name === 'NotAllowedError') { + /** + * Pass the error directly through. Platforms are overloading this error beyond what the spec + * defines and we don't want to overwrite potentially useful error messages. + */ + return new WebAuthnError({ + message: error.message, + code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY', + cause: error, + }); + } + else if (error.name === 'SecurityError') { + const effectiveDomain = window.location.hostname; + if (!(0, webauthn_1.isValidDomain)(effectiveDomain)) { + // https://www.w3.org/TR/webauthn-2/#sctn-discover-from-external-source (Step 5) + return new WebAuthnError({ + message: `${window.location.hostname} is an invalid domain`, + code: 'ERROR_INVALID_DOMAIN', + cause: error, + }); + } + else if (publicKey.rpId !== effectiveDomain) { + // https://www.w3.org/TR/webauthn-2/#sctn-discover-from-external-source (Step 6) + return new WebAuthnError({ + message: `The RP ID "${publicKey.rpId}" is invalid for this domain`, + code: 'ERROR_INVALID_RP_ID', + cause: error, + }); + } + } + else if (error.name === 'UnknownError') { + // https://www.w3.org/TR/webauthn-2/#sctn-op-get-assertion (Step 1) + // https://www.w3.org/TR/webauthn-2/#sctn-op-get-assertion (Step 12) + return new WebAuthnError({ + message: 'The authenticator was unable to process the specified options, or could not create a new assertion signature', + code: 'ERROR_AUTHENTICATOR_GENERAL_ERROR', + cause: error, + }); + } + return new WebAuthnError({ + message: 'a Non-Webauthn related error has occurred', + code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY', + cause: error, + }); +} +//# sourceMappingURL=webauthn.errors.js.map -Body.prototype = { - get body() { - return this[INTERNALS].body; - }, - - get bodyUsed() { - return this[INTERNALS].disturbed; - }, - - /** - * Decode response as ArrayBuffer - * - * @return Promise - */ - arrayBuffer() { - return consumeBody.call(this).then(function (buf) { - return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); - }); - }, - - /** - * Return raw response as Blob - * - * @return Promise - */ - blob() { - let ct = this.headers && this.headers.get('content-type') || ''; - return consumeBody.call(this).then(function (buf) { - return Object.assign( - // Prevent copying - new Blob([], { - type: ct.toLowerCase() - }), { - [BUFFER]: buf - }); - }); - }, - - /** - * Decode response as json - * - * @return Promise - */ - json() { - var _this2 = this; - - return consumeBody.call(this).then(function (buffer) { - try { - return JSON.parse(buffer.toString()); - } catch (err) { - return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); - } - }); - }, - - /** - * Decode response as text - * - * @return Promise - */ - text() { - return consumeBody.call(this).then(function (buffer) { - return buffer.toString(); - }); - }, - - /** - * Decode response as buffer (non-spec api) - * - * @return Promise - */ - buffer() { - return consumeBody.call(this); - }, - - /** - * Decode response as text, while automatically detecting the encoding and - * trying to decode to UTF-8 (non-spec api) - * - * @return Promise - */ - textConverted() { - var _this3 = this; - - return consumeBody.call(this).then(function (buffer) { - return convertBody(buffer, _this3.headers); - }); - } -}; +/***/ }), -// In browsers, all properties are enumerable. -Object.defineProperties(Body.prototype, { - body: { enumerable: true }, - bodyUsed: { enumerable: true }, - arrayBuffer: { enumerable: true }, - blob: { enumerable: true }, - json: { enumerable: true }, - text: { enumerable: true } -}); +/***/ 9451: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -Body.mixIn = function (proto) { - for (const name of Object.getOwnPropertyNames(Body.prototype)) { - // istanbul ignore else: future proof - if (!(name in proto)) { - const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); - Object.defineProperty(proto, name, desc); - } - } -}; +"use strict"; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.WebAuthnApi = exports.DEFAULT_REQUEST_OPTIONS = exports.DEFAULT_CREATION_OPTIONS = exports.webAuthnAbortService = exports.WebAuthnAbortService = exports.identifyAuthenticationError = exports.identifyRegistrationError = exports.isWebAuthnError = exports.WebAuthnError = void 0; +exports.deserializeCredentialCreationOptions = deserializeCredentialCreationOptions; +exports.deserializeCredentialRequestOptions = deserializeCredentialRequestOptions; +exports.serializeCredentialCreationResponse = serializeCredentialCreationResponse; +exports.serializeCredentialRequestResponse = serializeCredentialRequestResponse; +exports.isValidDomain = isValidDomain; +exports.createCredential = createCredential; +exports.getCredential = getCredential; +exports.mergeCredentialCreationOptions = mergeCredentialCreationOptions; +exports.mergeCredentialRequestOptions = mergeCredentialRequestOptions; +const tslib_1 = __nccwpck_require__(9808); +const base64url_1 = __nccwpck_require__(3649); +const errors_1 = __nccwpck_require__(9938); +const helpers_1 = __nccwpck_require__(4044); +const webauthn_errors_1 = __nccwpck_require__(7906); +Object.defineProperty(exports, "identifyAuthenticationError", ({ enumerable: true, get: function () { return webauthn_errors_1.identifyAuthenticationError; } })); +Object.defineProperty(exports, "identifyRegistrationError", ({ enumerable: true, get: function () { return webauthn_errors_1.identifyRegistrationError; } })); +Object.defineProperty(exports, "isWebAuthnError", ({ enumerable: true, get: function () { return webauthn_errors_1.isWebAuthnError; } })); +Object.defineProperty(exports, "WebAuthnError", ({ enumerable: true, get: function () { return webauthn_errors_1.WebAuthnError; } })); +/** + * WebAuthn abort service to manage ceremony cancellation. + * Ensures only one WebAuthn ceremony is active at a time to prevent "operation already in progress" errors. + * + * @experimental This class is experimental and may change in future releases + * @see {@link https://w3c.github.io/webauthn/#sctn-automation-webdriver-capability W3C WebAuthn Spec - Aborting Ceremonies} + */ +class WebAuthnAbortService { + /** + * Create an abort signal for a new WebAuthn operation. + * Automatically cancels any existing operation. + * + * @returns {AbortSignal} Signal to pass to navigator.credentials.create() or .get() + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal MDN - AbortSignal} + */ + createNewAbortSignal() { + // Abort any existing calls to navigator.credentials.create() or navigator.credentials.get() + if (this.controller) { + const abortError = new Error('Cancelling existing WebAuthn API call for new one'); + abortError.name = 'AbortError'; + this.controller.abort(abortError); + } + const newController = new AbortController(); + this.controller = newController; + return newController.signal; + } + /** + * Manually cancel the current WebAuthn operation. + * Useful for cleaning up when user cancels or navigates away. + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort MDN - AbortController.abort} + */ + cancelCeremony() { + if (this.controller) { + const abortError = new Error('Manually cancelling existing WebAuthn API call'); + abortError.name = 'AbortError'; + this.controller.abort(abortError); + this.controller = undefined; + } + } +} +exports.WebAuthnAbortService = WebAuthnAbortService; +/** + * Singleton instance to ensure only one WebAuthn ceremony is active at a time. + * This prevents "operation already in progress" errors when retrying WebAuthn operations. + * + * @experimental This instance is experimental and may change in future releases + */ +exports.webAuthnAbortService = new WebAuthnAbortService(); +/** + * Convert base64url encoded strings in WebAuthn credential creation options to ArrayBuffers + * as required by the WebAuthn browser API. + * Supports both native WebAuthn Level 3 parseCreationOptionsFromJSON and manual fallback. + * + * @param {ServerCredentialCreationOptions} options - JSON options from server with base64url encoded fields + * @returns {PublicKeyCredentialCreationOptionsFuture} Options ready for navigator.credentials.create() + * @see {@link https://w3c.github.io/webauthn/#sctn-parseCreationOptionsFromJSON W3C WebAuthn Spec - parseCreationOptionsFromJSON} + */ +function deserializeCredentialCreationOptions(options) { + if (!options) { + throw new Error('Credential creation options are required'); + } + // Check if the native parseCreationOptionsFromJSON method is available + if (typeof PublicKeyCredential !== 'undefined' && + 'parseCreationOptionsFromJSON' in PublicKeyCredential && + typeof PublicKeyCredential + .parseCreationOptionsFromJSON === 'function') { + // Use the native WebAuthn Level 3 method + return PublicKeyCredential.parseCreationOptionsFromJSON( + /** we assert the options here as typescript still doesn't know about future webauthn types */ + options); + } + // Fallback to manual parsing for browsers that don't support the native method + // Destructure to separate fields that need transformation + const { challenge: challengeStr, user: userOpts, excludeCredentials } = options, restOptions = tslib_1.__rest(options + // Convert challenge from base64url to ArrayBuffer + , ["challenge", "user", "excludeCredentials"]); + // Convert challenge from base64url to ArrayBuffer + const challenge = (0, base64url_1.base64UrlToUint8Array)(challengeStr).buffer; + // Convert user.id from base64url to ArrayBuffer + const user = Object.assign(Object.assign({}, userOpts), { id: (0, base64url_1.base64UrlToUint8Array)(userOpts.id).buffer }); + // Build the result object + const result = Object.assign(Object.assign({}, restOptions), { challenge, + user }); + // Only add excludeCredentials if it exists + if (excludeCredentials && excludeCredentials.length > 0) { + result.excludeCredentials = new Array(excludeCredentials.length); + for (let i = 0; i < excludeCredentials.length; i++) { + const cred = excludeCredentials[i]; + result.excludeCredentials[i] = Object.assign(Object.assign({}, cred), { id: (0, base64url_1.base64UrlToUint8Array)(cred.id).buffer, type: cred.type || 'public-key', + // Cast transports to handle future transport types like "cable" + transports: cred.transports }); + } + } + return result; +} /** - * Consume and convert an entire Body to a Buffer. - * - * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body + * Convert base64url encoded strings in WebAuthn credential request options to ArrayBuffers + * as required by the WebAuthn browser API. + * Supports both native WebAuthn Level 3 parseRequestOptionsFromJSON and manual fallback. + * + * @param {ServerCredentialRequestOptions} options - JSON options from server with base64url encoded fields + * @returns {PublicKeyCredentialRequestOptionsFuture} Options ready for navigator.credentials.get() + * @see {@link https://w3c.github.io/webauthn/#sctn-parseRequestOptionsFromJSON W3C WebAuthn Spec - parseRequestOptionsFromJSON} + */ +function deserializeCredentialRequestOptions(options) { + if (!options) { + throw new Error('Credential request options are required'); + } + // Check if the native parseRequestOptionsFromJSON method is available + if (typeof PublicKeyCredential !== 'undefined' && + 'parseRequestOptionsFromJSON' in PublicKeyCredential && + typeof PublicKeyCredential + .parseRequestOptionsFromJSON === 'function') { + // Use the native WebAuthn Level 3 method + return PublicKeyCredential.parseRequestOptionsFromJSON(options); + } + // Fallback to manual parsing for browsers that don't support the native method + // Destructure to separate fields that need transformation + const { challenge: challengeStr, allowCredentials } = options, restOptions = tslib_1.__rest(options + // Convert challenge from base64url to ArrayBuffer + , ["challenge", "allowCredentials"]); + // Convert challenge from base64url to ArrayBuffer + const challenge = (0, base64url_1.base64UrlToUint8Array)(challengeStr).buffer; + // Build the result object + const result = Object.assign(Object.assign({}, restOptions), { challenge }); + // Only add allowCredentials if it exists + if (allowCredentials && allowCredentials.length > 0) { + result.allowCredentials = new Array(allowCredentials.length); + for (let i = 0; i < allowCredentials.length; i++) { + const cred = allowCredentials[i]; + result.allowCredentials[i] = Object.assign(Object.assign({}, cred), { id: (0, base64url_1.base64UrlToUint8Array)(cred.id).buffer, type: cred.type || 'public-key', + // Cast transports to handle future transport types like "cable" + transports: cred.transports }); + } + } + return result; +} +/** + * Convert a registration/enrollment credential response to server format. + * Serializes binary fields to base64url for JSON transmission. + * Supports both native WebAuthn Level 3 toJSON and manual fallback. * - * @return Promise + * @param {RegistrationCredential} credential - Credential from navigator.credentials.create() + * @returns {RegistrationResponseJSON} JSON-serializable credential for server + * @see {@link https://w3c.github.io/webauthn/#dom-publickeycredential-tojson W3C WebAuthn Spec - toJSON} */ -function consumeBody() { - var _this4 = this; - - if (this[INTERNALS].disturbed) { - return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); - } - - this[INTERNALS].disturbed = true; - - if (this[INTERNALS].error) { - return Body.Promise.reject(this[INTERNALS].error); - } - - let body = this.body; - - // body is null - if (body === null) { - return Body.Promise.resolve(Buffer.alloc(0)); - } - - // body is blob - if (isBlob(body)) { - body = body.stream(); - } - - // body is buffer - if (Buffer.isBuffer(body)) { - return Body.Promise.resolve(body); - } - - // istanbul ignore if: should never happen - if (!(body instanceof Stream)) { - return Body.Promise.resolve(Buffer.alloc(0)); - } - - // body is stream - // get ready to actually consume the body - let accum = []; - let accumBytes = 0; - let abort = false; - - return new Body.Promise(function (resolve, reject) { - let resTimeout; - - // allow timeout on slow response body - if (_this4.timeout) { - resTimeout = setTimeout(function () { - abort = true; - reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); - }, _this4.timeout); - } - - // handle stream errors - body.on('error', function (err) { - if (err.name === 'AbortError') { - // if the request was aborted, reject with this Error - abort = true; - reject(err); - } else { - // other errors, such as incorrect content-encoding - reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); - } - }); - - body.on('data', function (chunk) { - if (abort || chunk === null) { - return; - } - - if (_this4.size && accumBytes + chunk.length > _this4.size) { - abort = true; - reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); - return; - } - - accumBytes += chunk.length; - accum.push(chunk); - }); - - body.on('end', function () { - if (abort) { - return; - } - - clearTimeout(resTimeout); - - try { - resolve(Buffer.concat(accum, accumBytes)); - } catch (err) { - // handle streams that have accumulated too much data (issue #414) - reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); - } - }); - }); +function serializeCredentialCreationResponse(credential) { + var _a; + // Check if the credential instance has the toJSON method + if ('toJSON' in credential && typeof credential.toJSON === 'function') { + // Use the native WebAuthn Level 3 method + return credential.toJSON(); + } + const credentialWithAttachment = credential; + return { + id: credential.id, + rawId: credential.id, + response: { + attestationObject: (0, base64url_1.bytesToBase64URL)(new Uint8Array(credential.response.attestationObject)), + clientDataJSON: (0, base64url_1.bytesToBase64URL)(new Uint8Array(credential.response.clientDataJSON)), + }, + type: 'public-key', + clientExtensionResults: credential.getClientExtensionResults(), + // Convert null to undefined and cast to AuthenticatorAttachment type + authenticatorAttachment: ((_a = credentialWithAttachment.authenticatorAttachment) !== null && _a !== void 0 ? _a : undefined), + }; } - /** - * Detect buffer encoding and convert to target encoding - * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding + * Convert an authentication/verification credential response to server format. + * Serializes binary fields to base64url for JSON transmission. + * Supports both native WebAuthn Level 3 toJSON and manual fallback. * - * @param Buffer buffer Incoming buffer - * @param String encoding Target encoding - * @return String + * @param {AuthenticationCredential} credential - Credential from navigator.credentials.get() + * @returns {AuthenticationResponseJSON} JSON-serializable credential for server + * @see {@link https://w3c.github.io/webauthn/#dom-publickeycredential-tojson W3C WebAuthn Spec - toJSON} */ -function convertBody(buffer, headers) { - { - throw new Error('The package `encoding` must be installed to use the textConverted() function'); - } - - const ct = headers.get('content-type'); - let charset = 'utf-8'; - let res, str; - - // header - if (ct) { - res = /charset=([^;]*)/i.exec(ct); - } - - // no charset in content type, peek at response body for at most 1024 bytes - str = buffer.slice(0, 1024).toString(); - - // html5 - if (!res && str) { - res = />} Created credential or error + * @see {@link https://w3c.github.io/webauthn/#sctn-createCredential W3C WebAuthn Spec - Create Credential} + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/create MDN - credentials.create} */ -function clone(instance) { - let p1, p2; - let body = instance.body; - - // don't allow cloning a used body - if (instance.bodyUsed) { - throw new Error('cannot clone body after it is used'); - } - - // check that body is a stream and not form-data object - // note: we can't clone the form-data object without having it as a dependency - if (body instanceof Stream && typeof body.getBoundary !== 'function') { - // tee instance body - p1 = new PassThrough(); - p2 = new PassThrough(); - body.pipe(p1); - body.pipe(p2); - // set instance body to teed body and return the other teed body - instance[INTERNALS].body = p1; - body = p2; - } - - return body; -} - -/** - * Performs the operation "extract a `Content-Type` value from |object|" as - * specified in the specification: - * https://fetch.spec.whatwg.org/#concept-bodyinit-extract - * - * This function assumes that instance.body is present. - * - * @param Mixed instance Any options.body input - */ -function extractContentType(body) { - if (body === null) { - // body is null - return null; - } else if (typeof body === 'string') { - // body is string - return 'text/plain;charset=UTF-8'; - } else if (isURLSearchParams(body)) { - // body is a URLSearchParams - return 'application/x-www-form-urlencoded;charset=UTF-8'; - } else if (isBlob(body)) { - // body is blob - return body.type || null; - } else if (Buffer.isBuffer(body)) { - // body is buffer - return null; - } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { - // body is ArrayBuffer - return null; - } else if (ArrayBuffer.isView(body)) { - // body is ArrayBufferView - return null; - } else if (typeof body.getBoundary === 'function') { - // detect form data input from form-data module - return `multipart/form-data;boundary=${body.getBoundary()}`; - } else if (body instanceof Stream) { - // body is stream - // can't really do much about this - return null; - } else { - // Body constructor defaults other things to string - return 'text/plain;charset=UTF-8'; - } +async function createCredential(options) { + try { + const response = await navigator.credentials.create( + /** we assert the type here until typescript types are updated */ + options); + if (!response) { + return { + data: null, + error: new webauthn_errors_1.WebAuthnUnknownError('Empty credential response', response), + }; + } + if (!(response instanceof PublicKeyCredential)) { + return { + data: null, + error: new webauthn_errors_1.WebAuthnUnknownError('Browser returned unexpected credential type', response), + }; + } + return { data: response, error: null }; + } + catch (err) { + return { + data: null, + error: (0, webauthn_errors_1.identifyRegistrationError)({ + error: err, + options, + }), + }; + } } - /** - * The Fetch Standard treats this as if "total bytes" is a property on the body. - * For us, we have to explicitly get it with a function. + * Get a WebAuthn credential using the browser's credentials API. + * Wraps navigator.credentials.get() with error handling. * - * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes - * - * @param Body instance Instance of Body - * @return Number? Number of bytes, or null if not possible + * @param {CredentialRequestOptions} options - Options including publicKey parameters + * @returns {Promise>} Retrieved credential or error + * @see {@link https://w3c.github.io/webauthn/#sctn-getAssertion W3C WebAuthn Spec - Get Assertion} + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get MDN - credentials.get} */ -function getTotalBytes(instance) { - const body = instance.body; - - - if (body === null) { - // body is null - return 0; - } else if (isBlob(body)) { - return body.size; - } else if (Buffer.isBuffer(body)) { - // body is buffer - return body.length; - } else if (body && typeof body.getLengthSync === 'function') { - // detect form data input from form-data module - if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x - body.hasKnownLength && body.hasKnownLength()) { - // 2.x - return body.getLengthSync(); - } - return null; - } else { - // body is stream - return null; - } +async function getCredential(options) { + try { + const response = await navigator.credentials.get( + /** we assert the type here until typescript types are updated */ + options); + if (!response) { + return { + data: null, + error: new webauthn_errors_1.WebAuthnUnknownError('Empty credential response', response), + }; + } + if (!(response instanceof PublicKeyCredential)) { + return { + data: null, + error: new webauthn_errors_1.WebAuthnUnknownError('Browser returned unexpected credential type', response), + }; + } + return { data: response, error: null }; + } + catch (err) { + return { + data: null, + error: (0, webauthn_errors_1.identifyAuthenticationError)({ + error: err, + options, + }), + }; + } +} +exports.DEFAULT_CREATION_OPTIONS = { + hints: ['security-key'], + authenticatorSelection: { + authenticatorAttachment: 'cross-platform', + requireResidentKey: false, + /** set to preferred because older yubikeys don't have PIN/Biometric */ + userVerification: 'preferred', + residentKey: 'discouraged', + }, + attestation: 'direct', +}; +exports.DEFAULT_REQUEST_OPTIONS = { + /** set to preferred because older yubikeys don't have PIN/Biometric */ + userVerification: 'preferred', + hints: ['security-key'], + attestation: 'direct', +}; +function deepMerge(...sources) { + const isObject = (val) => val !== null && typeof val === 'object' && !Array.isArray(val); + const isArrayBufferLike = (val) => val instanceof ArrayBuffer || ArrayBuffer.isView(val); + const result = {}; + for (const source of sources) { + if (!source) + continue; + for (const key in source) { + const value = source[key]; + if (value === undefined) + continue; + if (Array.isArray(value)) { + // preserve array reference, including unions like AuthenticatorTransport[] + result[key] = value; + } + else if (isArrayBufferLike(value)) { + result[key] = value; + } + else if (isObject(value)) { + const existing = result[key]; + if (isObject(existing)) { + result[key] = deepMerge(existing, value); + } + else { + result[key] = deepMerge(value); + } + } + else { + result[key] = value; + } + } + } + return result; } - /** - * Write a Body to a Node.js WritableStream (e.g. http.Request) object. + * Merges WebAuthn credential creation options with overrides. + * Sets sensible defaults for authenticator selection and extensions. * - * @param Body instance Instance of Body - * @return Void + * @param {PublicKeyCredentialCreationOptionsFuture} baseOptions - The base options from the server + * @param {PublicKeyCredentialCreationOptionsFuture} overrides - Optional overrides to apply + * @param {string} friendlyName - Optional friendly name for the credential + * @returns {PublicKeyCredentialCreationOptionsFuture} Merged credential creation options + * @see {@link https://w3c.github.io/webauthn/#dictdef-authenticatorselectioncriteria W3C WebAuthn Spec - AuthenticatorSelectionCriteria} */ -function writeToStream(dest, instance) { - const body = instance.body; - - - if (body === null) { - // body is null - dest.end(); - } else if (isBlob(body)) { - body.stream().pipe(dest); - } else if (Buffer.isBuffer(body)) { - // body is buffer - dest.write(body); - dest.end(); - } else { - // body is stream - body.pipe(dest); - } +function mergeCredentialCreationOptions(baseOptions, overrides) { + return deepMerge(exports.DEFAULT_CREATION_OPTIONS, baseOptions, overrides || {}); } - -// expose Promise -Body.Promise = global.Promise; - /** - * headers.js + * Merges WebAuthn credential request options with overrides. + * Sets sensible defaults for user verification and hints. * - * Headers class offers convenient helpers + * @param {PublicKeyCredentialRequestOptionsFuture} baseOptions - The base options from the server + * @param {PublicKeyCredentialRequestOptionsFuture} overrides - Optional overrides to apply + * @returns {PublicKeyCredentialRequestOptionsFuture} Merged credential request options + * @see {@link https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptions W3C WebAuthn Spec - PublicKeyCredentialRequestOptions} */ - -const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/; -const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/; - -function validateName(name) { - name = `${name}`; - if (invalidTokenRegex.test(name) || name === '') { - throw new TypeError(`${name} is not a legal HTTP header name`); - } -} - -function validateValue(value) { - value = `${value}`; - if (invalidHeaderCharRegex.test(value)) { - throw new TypeError(`${value} is not a legal HTTP header value`); - } +function mergeCredentialRequestOptions(baseOptions, overrides) { + return deepMerge(exports.DEFAULT_REQUEST_OPTIONS, baseOptions, overrides || {}); } - /** - * Find the key in the map object given a header name. - * - * Returns undefined if not found. + * WebAuthn API wrapper for Supabase Auth. + * Provides methods for enrolling, challenging, verifying, authenticating, and registering WebAuthn credentials. * - * @param String name Header name - * @return String|Undefined + * @experimental This API is experimental and may change in future releases + * @see {@link https://w3c.github.io/webauthn/ W3C WebAuthn Specification} + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API MDN - Web Authentication API} */ -function find(map, name) { - name = name.toLowerCase(); - for (const key in map) { - if (key.toLowerCase() === name) { - return key; - } - } - return undefined; -} - -const MAP = Symbol('map'); -class Headers { - /** - * Headers class - * - * @param Object headers Response headers - * @return Void - */ - constructor() { - let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; - - this[MAP] = Object.create(null); - - if (init instanceof Headers) { - const rawHeaders = init.raw(); - const headerNames = Object.keys(rawHeaders); - - for (const headerName of headerNames) { - for (const value of rawHeaders[headerName]) { - this.append(headerName, value); - } - } - - return; - } - - // We don't worry about converting prop to ByteString here as append() - // will handle it. - if (init == null) ; else if (typeof init === 'object') { - const method = init[Symbol.iterator]; - if (method != null) { - if (typeof method !== 'function') { - throw new TypeError('Header pairs must be iterable'); - } - - // sequence> - // Note: per spec we have to first exhaust the lists then process them - const pairs = []; - for (const pair of init) { - if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { - throw new TypeError('Each header pair must be iterable'); - } - pairs.push(Array.from(pair)); - } - - for (const pair of pairs) { - if (pair.length !== 2) { - throw new TypeError('Each header pair must be a name/value tuple'); - } - this.append(pair[0], pair[1]); - } - } else { - // record - for (const key of Object.keys(init)) { - const value = init[key]; - this.append(key, value); - } - } - } else { - throw new TypeError('Provided initializer must be an object'); - } - } - - /** - * Return combined header value given name - * - * @param String name Header name - * @return Mixed - */ - get(name) { - name = `${name}`; - validateName(name); - const key = find(this[MAP], name); - if (key === undefined) { - return null; - } - - return this[MAP][key].join(', '); - } - - /** - * Iterate over all headers - * - * @param Function callback Executed for each item with parameters (value, name, thisArg) - * @param Boolean thisArg `this` context for callback function - * @return Void - */ - forEach(callback) { - let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; - - let pairs = getHeaders(this); - let i = 0; - while (i < pairs.length) { - var _pairs$i = pairs[i]; - const name = _pairs$i[0], - value = _pairs$i[1]; - - callback.call(thisArg, value, name, this); - pairs = getHeaders(this); - i++; - } - } +class WebAuthnApi { + constructor(client) { + this.client = client; + // Bind all methods so they can be destructured + this.enroll = this._enroll.bind(this); + this.challenge = this._challenge.bind(this); + this.verify = this._verify.bind(this); + this.authenticate = this._authenticate.bind(this); + this.register = this._register.bind(this); + } + /** + * Enroll a new WebAuthn factor. + * Creates an unverified WebAuthn factor that must be verified with a credential. + * + * @experimental This method is experimental and may change in future releases + * @param {Omit} params - Enrollment parameters (friendlyName required) + * @returns {Promise} Enrolled factor details or error + * @see {@link https://w3c.github.io/webauthn/#sctn-registering-a-new-credential W3C WebAuthn Spec - Registering a New Credential} + */ + async _enroll(params) { + return this.client.mfa.enroll(Object.assign(Object.assign({}, params), { factorType: 'webauthn' })); + } + /** + * Challenge for WebAuthn credential creation or authentication. + * Combines server challenge with browser credential operations. + * Handles both registration (create) and authentication (request) flows. + * + * @experimental This method is experimental and may change in future releases + * @param {MFAChallengeWebauthnParams & { friendlyName?: string; signal?: AbortSignal }} params - Challenge parameters including factorId + * @param {Object} overrides - Allows you to override the parameters passed to navigator.credentials + * @param {PublicKeyCredentialCreationOptionsFuture} overrides.create - Override options for credential creation + * @param {PublicKeyCredentialRequestOptionsFuture} overrides.request - Override options for credential request + * @returns {Promise} Challenge response with credential or error + * @see {@link https://w3c.github.io/webauthn/#sctn-credential-creation W3C WebAuthn Spec - Credential Creation} + * @see {@link https://w3c.github.io/webauthn/#sctn-verifying-assertion W3C WebAuthn Spec - Verifying Assertion} + */ + async _challenge({ factorId, webauthn, friendlyName, signal, }, overrides) { + var _a; + try { + // Get challenge from server using the client's MFA methods + const { data: challengeResponse, error: challengeError } = await this.client.mfa.challenge({ + factorId, + webauthn, + }); + if (!challengeResponse) { + return { data: null, error: challengeError }; + } + const abortSignal = signal !== null && signal !== void 0 ? signal : exports.webAuthnAbortService.createNewAbortSignal(); + /** webauthn will fail if either of the name/displayname are blank */ + if (challengeResponse.webauthn.type === 'create') { + const { user } = challengeResponse.webauthn.credential_options.publicKey; + if (!user.name) { + // Preserve original format: use friendlyName if provided, otherwise fetch fallback + // This maintains backward compatibility with the ${user.id}:${name} format + const nameToUse = friendlyName; + if (!nameToUse) { + // Only fetch user data if friendlyName is not provided (bug fix for null friendlyName) + const currentUser = await this.client.getUser(); + const userData = currentUser.data.user; + const fallbackName = ((_a = userData === null || userData === void 0 ? void 0 : userData.user_metadata) === null || _a === void 0 ? void 0 : _a.name) || (userData === null || userData === void 0 ? void 0 : userData.email) || (userData === null || userData === void 0 ? void 0 : userData.id) || 'User'; + user.name = `${user.id}:${fallbackName}`; + } + else { + user.name = `${user.id}:${nameToUse}`; + } + } + if (!user.displayName) { + user.displayName = user.name; + } + } + switch (challengeResponse.webauthn.type) { + case 'create': { + const options = mergeCredentialCreationOptions(challengeResponse.webauthn.credential_options.publicKey, overrides === null || overrides === void 0 ? void 0 : overrides.create); + const { data, error } = await createCredential({ + publicKey: options, + signal: abortSignal, + }); + if (data) { + return { + data: { + factorId, + challengeId: challengeResponse.id, + webauthn: { + type: challengeResponse.webauthn.type, + credential_response: data, + }, + }, + error: null, + }; + } + return { data: null, error }; + } + case 'request': { + const options = mergeCredentialRequestOptions(challengeResponse.webauthn.credential_options.publicKey, overrides === null || overrides === void 0 ? void 0 : overrides.request); + const { data, error } = await getCredential(Object.assign(Object.assign({}, challengeResponse.webauthn.credential_options), { publicKey: options, signal: abortSignal })); + if (data) { + return { + data: { + factorId, + challengeId: challengeResponse.id, + webauthn: { + type: challengeResponse.webauthn.type, + credential_response: data, + }, + }, + error: null, + }; + } + return { data: null, error }; + } + } + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: null, error }; + } + return { + data: null, + error: new errors_1.AuthUnknownError('Unexpected error in challenge', error), + }; + } + } + /** + * Verify a WebAuthn credential with the server. + * Completes the WebAuthn ceremony by sending the credential to the server for verification. + * + * @experimental This method is experimental and may change in future releases + * @param {Object} params - Verification parameters + * @param {string} params.challengeId - ID of the challenge being verified + * @param {string} params.factorId - ID of the WebAuthn factor + * @param {MFAVerifyWebauthnParams['webauthn']} params.webauthn - WebAuthn credential response + * @returns {Promise} Verification result with session or error + * @see {@link https://w3c.github.io/webauthn/#sctn-verifying-assertion W3C WebAuthn Spec - Verifying an Authentication Assertion} + * */ + async _verify({ challengeId, factorId, webauthn, }) { + return this.client.mfa.verify({ + factorId, + challengeId, + webauthn: webauthn, + }); + } + /** + * Complete WebAuthn authentication flow. + * Performs challenge and verification in a single operation for existing credentials. + * + * @experimental This method is experimental and may change in future releases + * @param {Object} params - Authentication parameters + * @param {string} params.factorId - ID of the WebAuthn factor to authenticate with + * @param {Object} params.webauthn - WebAuthn configuration + * @param {string} params.webauthn.rpId - Relying Party ID (defaults to current hostname) + * @param {string[]} params.webauthn.rpOrigins - Allowed origins (defaults to current origin) + * @param {AbortSignal} params.webauthn.signal - Optional abort signal + * @param {PublicKeyCredentialRequestOptionsFuture} overrides - Override options for navigator.credentials.get + * @returns {Promise>} Authentication result + * @see {@link https://w3c.github.io/webauthn/#sctn-authentication W3C WebAuthn Spec - Authentication Ceremony} + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialRequestOptions MDN - PublicKeyCredentialRequestOptions} + */ + async _authenticate({ factorId, webauthn: { rpId = typeof window !== 'undefined' ? window.location.hostname : undefined, rpOrigins = typeof window !== 'undefined' ? [window.location.origin] : undefined, signal, } = {}, }, overrides) { + if (!rpId) { + return { + data: null, + error: new errors_1.AuthError('rpId is required for WebAuthn authentication'), + }; + } + try { + if (!browserSupportsWebAuthn()) { + return { + data: null, + error: new errors_1.AuthUnknownError('Browser does not support WebAuthn', null), + }; + } + // Get challenge and credential + const { data: challengeResponse, error: challengeError } = await this.challenge({ + factorId, + webauthn: { rpId, rpOrigins }, + signal, + }, { request: overrides }); + if (!challengeResponse) { + return { data: null, error: challengeError }; + } + const { webauthn } = challengeResponse; + // Verify credential + return this._verify({ + factorId, + challengeId: challengeResponse.challengeId, + webauthn: { + type: webauthn.type, + rpId, + rpOrigins, + credential_response: webauthn.credential_response, + }, + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: null, error }; + } + return { + data: null, + error: new errors_1.AuthUnknownError('Unexpected error in authenticate', error), + }; + } + } + /** + * Complete WebAuthn registration flow. + * Performs enrollment, challenge, and verification in a single operation for new credentials. + * + * @experimental This method is experimental and may change in future releases + * @param {Object} params - Registration parameters + * @param {string} params.friendlyName - User-friendly name for the credential + * @param {string} params.rpId - Relying Party ID (defaults to current hostname) + * @param {string[]} params.rpOrigins - Allowed origins (defaults to current origin) + * @param {AbortSignal} params.signal - Optional abort signal + * @param {PublicKeyCredentialCreationOptionsFuture} overrides - Override options for navigator.credentials.create + * @returns {Promise>} Registration result + * @see {@link https://w3c.github.io/webauthn/#sctn-registering-a-new-credential W3C WebAuthn Spec - Registration Ceremony} + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialCreationOptions MDN - PublicKeyCredentialCreationOptions} + */ + async _register({ friendlyName, webauthn: { rpId = typeof window !== 'undefined' ? window.location.hostname : undefined, rpOrigins = typeof window !== 'undefined' ? [window.location.origin] : undefined, signal, } = {}, }, overrides) { + if (!rpId) { + return { + data: null, + error: new errors_1.AuthError('rpId is required for WebAuthn registration'), + }; + } + try { + if (!browserSupportsWebAuthn()) { + return { + data: null, + error: new errors_1.AuthUnknownError('Browser does not support WebAuthn', null), + }; + } + // Enroll factor + const { data: factor, error: enrollError } = await this._enroll({ + friendlyName, + }); + if (!factor) { + await this.client.mfa + .listFactors() + .then((factors) => { + var _a; + return (_a = factors.data) === null || _a === void 0 ? void 0 : _a.all.find((v) => v.factor_type === 'webauthn' && + v.friendly_name === friendlyName && + v.status !== 'unverified'); + }) + .then((factor) => (factor ? this.client.mfa.unenroll({ factorId: factor === null || factor === void 0 ? void 0 : factor.id }) : void 0)); + return { data: null, error: enrollError }; + } + // Get challenge and create credential + const { data: challengeResponse, error: challengeError } = await this._challenge({ + factorId: factor.id, + friendlyName: factor.friendly_name, + webauthn: { rpId, rpOrigins }, + signal, + }, { + create: overrides, + }); + if (!challengeResponse) { + return { data: null, error: challengeError }; + } + return this._verify({ + factorId: factor.id, + challengeId: challengeResponse.challengeId, + webauthn: { + rpId, + rpOrigins, + type: challengeResponse.webauthn.type, + credential_response: challengeResponse.webauthn.credential_response, + }, + }); + } + catch (error) { + if ((0, errors_1.isAuthError)(error)) { + return { data: null, error }; + } + return { + data: null, + error: new errors_1.AuthUnknownError('Unexpected error in register', error), + }; + } + } +} +exports.WebAuthnApi = WebAuthnApi; +//# sourceMappingURL=webauthn.js.map - /** - * Overwrite header values given name - * - * @param String name Header name - * @param String value Header value - * @return Void - */ - set(name, value) { - name = `${name}`; - value = `${value}`; - validateName(name); - validateValue(value); - const key = find(this[MAP], name); - this[MAP][key !== undefined ? key : name] = [value]; - } +/***/ }), - /** - * Append a value onto existing header - * - * @param String name Header name - * @param String value Header value - * @return Void - */ - append(name, value) { - name = `${name}`; - value = `${value}`; - validateName(name); - validateValue(value); - const key = find(this[MAP], name); - if (key !== undefined) { - this[MAP][key].push(value); - } else { - this[MAP][name] = [value]; - } - } +/***/ 9808: +/***/ ((module) => { - /** - * Check for header name existence - * - * @param String name Header name - * @return Boolean - */ - has(name) { - name = `${name}`; - validateName(name); - return find(this[MAP], name) !== undefined; - } +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +/* global global, define, Symbol, Reflect, Promise, SuppressedError, Iterator */ +var __extends; +var __assign; +var __rest; +var __decorate; +var __param; +var __esDecorate; +var __runInitializers; +var __propKey; +var __setFunctionName; +var __metadata; +var __awaiter; +var __generator; +var __exportStar; +var __values; +var __read; +var __spread; +var __spreadArrays; +var __spreadArray; +var __await; +var __asyncGenerator; +var __asyncDelegator; +var __asyncValues; +var __makeTemplateObject; +var __importStar; +var __importDefault; +var __classPrivateFieldGet; +var __classPrivateFieldSet; +var __classPrivateFieldIn; +var __createBinding; +var __addDisposableResource; +var __disposeResources; +var __rewriteRelativeImportExtension; +(function (factory) { + var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {}; + if (typeof define === "function" && define.amd) { + define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); }); + } + else if ( true && typeof module.exports === "object") { + factory(createExporter(root, createExporter(module.exports))); + } + else { + factory(createExporter(root)); + } + function createExporter(exports, previous) { + if (exports !== root) { + if (typeof Object.create === "function") { + Object.defineProperty(exports, "__esModule", { value: true }); + } + else { + exports.__esModule = true; + } + } + return function (id, v) { return exports[id] = previous ? previous(id, v) : v; }; + } +}) +(function (exporter) { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + + __extends = function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; + + __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; + }; + + __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; + }; + + __decorate = function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + 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; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + + __param = function (paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } + }; + + __esDecorate = function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; + }; + + __runInitializers = function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; + }; + + __propKey = function (x) { + return typeof x === "symbol" ? x : "".concat(x); + }; + + __setFunctionName = function (f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); + }; + + __metadata = function (metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); + }; + + __awaiter = function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + + __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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); + return g.next = verb(0), g["throw"] = verb(1), g["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 (g && (g = 0, op[0] && (_ = 0)), _) 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 }; + } + }; + + __exportStar = function(m, o) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); + }; + + __createBinding = Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + }); + + __values = function (o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + }; + + __read = function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; + }; + + /** @deprecated */ + __spread = function () { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; + }; + + /** @deprecated */ + __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; + }; + + __spreadArray = function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); + }; + + __await = function (v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); + }; + + __asyncGenerator = function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; + function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } + function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } + }; + + __asyncDelegator = function (o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; + function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } + }; + + __asyncValues = function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + 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); + 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); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } + }; + + __makeTemplateObject = function (cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; + }; + + var __setModuleDefault = Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }; + + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + + __importStar = function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; + + __importDefault = function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + + __classPrivateFieldGet = function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); + }; + + __classPrivateFieldSet = function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; + }; + + __classPrivateFieldIn = function (state, receiver) { + if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); + return typeof state === "function" ? receiver === state : state.has(receiver); + }; + + __addDisposableResource = function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose, inner; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + if (async) inner = dispose; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } }; + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; + }; + + var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; + }; + + __disposeResources = function (env) { + function fail(e) { + env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + var r, s = 0; + function next() { + while (r = env.stack.pop()) { + try { + if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); + if (r.dispose) { + var result = r.dispose.call(r.value); + if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + else s |= 1; + } + catch (e) { + fail(e); + } + } + if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); + if (env.hasError) throw env.error; + } + return next(); + }; + + __rewriteRelativeImportExtension = function (path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); + } + return path; + }; + + exporter("__extends", __extends); + exporter("__assign", __assign); + exporter("__rest", __rest); + exporter("__decorate", __decorate); + exporter("__param", __param); + exporter("__esDecorate", __esDecorate); + exporter("__runInitializers", __runInitializers); + exporter("__propKey", __propKey); + exporter("__setFunctionName", __setFunctionName); + exporter("__metadata", __metadata); + exporter("__awaiter", __awaiter); + exporter("__generator", __generator); + exporter("__exportStar", __exportStar); + exporter("__createBinding", __createBinding); + exporter("__values", __values); + exporter("__read", __read); + exporter("__spread", __spread); + exporter("__spreadArrays", __spreadArrays); + exporter("__spreadArray", __spreadArray); + exporter("__await", __await); + exporter("__asyncGenerator", __asyncGenerator); + exporter("__asyncDelegator", __asyncDelegator); + exporter("__asyncValues", __asyncValues); + exporter("__makeTemplateObject", __makeTemplateObject); + exporter("__importStar", __importStar); + exporter("__importDefault", __importDefault); + exporter("__classPrivateFieldGet", __classPrivateFieldGet); + exporter("__classPrivateFieldSet", __classPrivateFieldSet); + exporter("__classPrivateFieldIn", __classPrivateFieldIn); + exporter("__addDisposableResource", __addDisposableResource); + exporter("__disposeResources", __disposeResources); + exporter("__rewriteRelativeImportExtension", __rewriteRelativeImportExtension); +}); + +0 && (0); - /** - * Delete all header values given name - * - * @param String name Header name - * @return Void - */ - delete(name) { - name = `${name}`; - validateName(name); - const key = find(this[MAP], name); - if (key !== undefined) { - delete this[MAP][key]; - } - } - /** - * Return raw headers (non-spec api) - * - * @return Object - */ - raw() { - return this[MAP]; - } +/***/ }), - /** - * Get an iterator on keys. - * - * @return Iterator - */ - keys() { - return createHeadersIterator(this, 'key'); - } +/***/ 9904: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - /** - * Get an iterator on values. - * - * @return Iterator - */ - values() { - return createHeadersIterator(this, 'value'); - } +"use strict"; - /** - * Get an iterator on entries. - * - * This is the default iterator of the Headers object. - * - * @return Iterator - */ - [Symbol.iterator]() { - return createHeadersIterator(this, 'key+value'); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.FunctionsClient = void 0; +const tslib_1 = __nccwpck_require__(6479); +const helper_1 = __nccwpck_require__(618); +const types_1 = __nccwpck_require__(3136); +/** + * Client for invoking Supabase Edge Functions. + */ +class FunctionsClient { + /** + * Creates a new Functions client bound to an Edge Functions URL. + * + * @example + * ```ts + * import { FunctionsClient, FunctionRegion } from '@supabase/functions-js' + * + * const functions = new FunctionsClient('https://xyzcompany.supabase.co/functions/v1', { + * headers: { apikey: 'public-anon-key' }, + * region: FunctionRegion.UsEast1, + * }) + * ``` + */ + constructor(url, { headers = {}, customFetch, region = types_1.FunctionRegion.Any, } = {}) { + this.url = url; + this.headers = headers; + this.region = region; + this.fetch = (0, helper_1.resolveFetch)(customFetch); + } + /** + * Updates the authorization header + * @param token - the new jwt token sent in the authorisation header + * @example + * ```ts + * functions.setAuth(session.access_token) + * ``` + */ + setAuth(token) { + this.headers.Authorization = `Bearer ${token}`; + } + /** + * Invokes a function + * @param functionName - The name of the Function to invoke. + * @param options - Options for invoking the Function. + * @example + * ```ts + * const { data, error } = await functions.invoke('hello-world', { + * body: { name: 'Ada' }, + * }) + * ``` + */ + invoke(functionName_1) { + return tslib_1.__awaiter(this, arguments, void 0, function* (functionName, options = {}) { + var _a; + let timeoutId; + let timeoutController; + try { + const { headers, method, body: functionArgs, signal, timeout } = options; + let _headers = {}; + let { region } = options; + if (!region) { + region = this.region; + } + // Add region as query parameter using URL API + const url = new URL(`${this.url}/${functionName}`); + if (region && region !== 'any') { + _headers['x-region'] = region; + url.searchParams.set('forceFunctionRegion', region); + } + let body; + if (functionArgs && + ((headers && !Object.prototype.hasOwnProperty.call(headers, 'Content-Type')) || !headers)) { + if ((typeof Blob !== 'undefined' && functionArgs instanceof Blob) || + functionArgs instanceof ArrayBuffer) { + // will work for File as File inherits Blob + // also works for ArrayBuffer as it is the same underlying structure as a Blob + _headers['Content-Type'] = 'application/octet-stream'; + body = functionArgs; + } + else if (typeof functionArgs === 'string') { + // plain string + _headers['Content-Type'] = 'text/plain'; + body = functionArgs; + } + else if (typeof FormData !== 'undefined' && functionArgs instanceof FormData) { + // don't set content-type headers + // Request will automatically add the right boundary value + body = functionArgs; + } + else { + // default, assume this is JSON + _headers['Content-Type'] = 'application/json'; + body = JSON.stringify(functionArgs); + } + } + else { + if (functionArgs && + typeof functionArgs !== 'string' && + !(typeof Blob !== 'undefined' && functionArgs instanceof Blob) && + !(functionArgs instanceof ArrayBuffer) && + !(typeof FormData !== 'undefined' && functionArgs instanceof FormData)) { + body = JSON.stringify(functionArgs); + } + else { + body = functionArgs; + } + } + // Handle timeout by creating an AbortController + let effectiveSignal = signal; + if (timeout) { + timeoutController = new AbortController(); + timeoutId = setTimeout(() => timeoutController.abort(), timeout); + // If user provided their own signal, we need to respect both + if (signal) { + effectiveSignal = timeoutController.signal; + // If the user's signal is aborted, abort our timeout controller too + signal.addEventListener('abort', () => timeoutController.abort()); + } + else { + effectiveSignal = timeoutController.signal; + } + } + const response = yield this.fetch(url.toString(), { + method: method || 'POST', + // headers priority is (high to low): + // 1. invoke-level headers + // 2. client-level headers + // 3. default Content-Type header + headers: Object.assign(Object.assign(Object.assign({}, _headers), this.headers), headers), + body, + signal: effectiveSignal, + }).catch((fetchError) => { + throw new types_1.FunctionsFetchError(fetchError); + }); + const isRelayError = response.headers.get('x-relay-error'); + if (isRelayError && isRelayError === 'true') { + throw new types_1.FunctionsRelayError(response); + } + if (!response.ok) { + throw new types_1.FunctionsHttpError(response); + } + let responseType = ((_a = response.headers.get('Content-Type')) !== null && _a !== void 0 ? _a : 'text/plain').split(';')[0].trim(); + let data; + if (responseType === 'application/json') { + data = yield response.json(); + } + else if (responseType === 'application/octet-stream' || + responseType === 'application/pdf') { + data = yield response.blob(); + } + else if (responseType === 'text/event-stream') { + data = response; + } + else if (responseType === 'multipart/form-data') { + data = yield response.formData(); + } + else { + // default to text + data = yield response.text(); + } + return { data, error: null, response }; + } + catch (error) { + return { + data: null, + error, + response: error instanceof types_1.FunctionsHttpError || error instanceof types_1.FunctionsRelayError + ? error.context + : undefined, + }; + } + finally { + // Clear the timeout if it was set + if (timeoutId) { + clearTimeout(timeoutId); + } + } + }); + } } -Headers.prototype.entries = Headers.prototype[Symbol.iterator]; - -Object.defineProperty(Headers.prototype, Symbol.toStringTag, { - value: 'Headers', - writable: false, - enumerable: false, - configurable: true -}); +exports.FunctionsClient = FunctionsClient; +//# sourceMappingURL=FunctionsClient.js.map -Object.defineProperties(Headers.prototype, { - get: { enumerable: true }, - forEach: { enumerable: true }, - set: { enumerable: true }, - append: { enumerable: true }, - has: { enumerable: true }, - delete: { enumerable: true }, - keys: { enumerable: true }, - values: { enumerable: true }, - entries: { enumerable: true } -}); +/***/ }), -function getHeaders(headers) { - let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; +/***/ 618: +/***/ ((__unused_webpack_module, exports) => { - const keys = Object.keys(headers[MAP]).sort(); - return keys.map(kind === 'key' ? function (k) { - return k.toLowerCase(); - } : kind === 'value' ? function (k) { - return headers[MAP][k].join(', '); - } : function (k) { - return [k.toLowerCase(), headers[MAP][k].join(', ')]; - }); -} +"use strict"; -const INTERNAL = Symbol('internal'); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.resolveFetch = void 0; +const resolveFetch = (customFetch) => { + if (customFetch) { + return (...args) => customFetch(...args); + } + return (...args) => fetch(...args); +}; +exports.resolveFetch = resolveFetch; +//# sourceMappingURL=helper.js.map -function createHeadersIterator(target, kind) { - const iterator = Object.create(HeadersIteratorPrototype); - iterator[INTERNAL] = { - target, - kind, - index: 0 - }; - return iterator; -} +/***/ }), -const HeadersIteratorPrototype = Object.setPrototypeOf({ - next() { - // istanbul ignore if - if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { - throw new TypeError('Value of `this` is not a HeadersIterator'); - } +/***/ 8519: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - var _INTERNAL = this[INTERNAL]; - const target = _INTERNAL.target, - kind = _INTERNAL.kind, - index = _INTERNAL.index; +"use strict"; +var __webpack_unused_export__; - const values = getHeaders(target, kind); - const len = values.length; - if (index >= len) { - return { - value: undefined, - done: true - }; - } +__webpack_unused_export__ = ({ value: true }); +__webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = exports.bE = void 0; +var FunctionsClient_1 = __nccwpck_require__(9904); +Object.defineProperty(exports, "bE", ({ enumerable: true, get: function () { return FunctionsClient_1.FunctionsClient; } })); +var types_1 = __nccwpck_require__(3136); +__webpack_unused_export__ = ({ enumerable: true, get: function () { return types_1.FunctionsError; } }); +__webpack_unused_export__ = ({ enumerable: true, get: function () { return types_1.FunctionsFetchError; } }); +__webpack_unused_export__ = ({ enumerable: true, get: function () { return types_1.FunctionsHttpError; } }); +__webpack_unused_export__ = ({ enumerable: true, get: function () { return types_1.FunctionsRelayError; } }); +__webpack_unused_export__ = ({ enumerable: true, get: function () { return types_1.FunctionRegion; } }); +//# sourceMappingURL=index.js.map - this[INTERNAL].index = index + 1; +/***/ }), - return { - value: values[index], - done: false - }; - } -}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); +/***/ 3136: +/***/ ((__unused_webpack_module, exports) => { -Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { - value: 'HeadersIterator', - writable: false, - enumerable: false, - configurable: true -}); +"use strict"; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.FunctionRegion = exports.FunctionsHttpError = exports.FunctionsRelayError = exports.FunctionsFetchError = exports.FunctionsError = void 0; /** - * Export the Headers object in a form that Node.js can consume. + * Base error for Supabase Edge Function invocations. * - * @param Headers headers - * @return Object - */ -function exportNodeCompatibleHeaders(headers) { - const obj = Object.assign({ __proto__: null }, headers[MAP]); - - // http.request() only supports string as Host header. This hack makes - // specifying custom Host header possible. - const hostHeaderKey = find(headers[MAP], 'Host'); - if (hostHeaderKey !== undefined) { - obj[hostHeaderKey] = obj[hostHeaderKey][0]; - } - - return obj; -} - -/** - * Create a Headers object from an object of headers, ignoring those that do - * not conform to HTTP grammar productions. + * @example + * ```ts + * import { FunctionsError } from '@supabase/functions-js' * - * @param Object obj Object of headers - * @return Headers + * throw new FunctionsError('Unexpected error invoking function', 'FunctionsError', { + * requestId: 'abc123', + * }) + * ``` */ -function createHeadersLenient(obj) { - const headers = new Headers(); - for (const name of Object.keys(obj)) { - if (invalidTokenRegex.test(name)) { - continue; - } - if (Array.isArray(obj[name])) { - for (const val of obj[name]) { - if (invalidHeaderCharRegex.test(val)) { - continue; - } - if (headers[MAP][name] === undefined) { - headers[MAP][name] = [val]; - } else { - headers[MAP][name].push(val); - } - } - } else if (!invalidHeaderCharRegex.test(obj[name])) { - headers[MAP][name] = [obj[name]]; - } - } - return headers; +class FunctionsError extends Error { + constructor(message, name = 'FunctionsError', context) { + super(message); + this.name = name; + this.context = context; + } } - -const INTERNALS$1 = Symbol('Response internals'); - -// fix an issue where "STATUS_CODES" aren't a named export for node <10 -const STATUS_CODES = http.STATUS_CODES; - +exports.FunctionsError = FunctionsError; /** - * Response class + * Error thrown when the network request to an Edge Function fails. * - * @param Stream body Readable stream - * @param Object opts Response options - * @return Void - */ -class Response { - constructor() { - let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - Body.call(this, body, opts); - - const status = opts.status || 200; - const headers = new Headers(opts.headers); - - if (body != null && !headers.has('Content-Type')) { - const contentType = extractContentType(body); - if (contentType) { - headers.append('Content-Type', contentType); - } - } - - this[INTERNALS$1] = { - url: opts.url, - status, - statusText: opts.statusText || STATUS_CODES[status], - headers, - counter: opts.counter - }; - } - - get url() { - return this[INTERNALS$1].url || ''; - } - - get status() { - return this[INTERNALS$1].status; - } - - /** - * Convenience property representing if the request ended normally - */ - get ok() { - return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; - } - - get redirected() { - return this[INTERNALS$1].counter > 0; - } - - get statusText() { - return this[INTERNALS$1].statusText; - } - - get headers() { - return this[INTERNALS$1].headers; - } - - /** - * Clone this response - * - * @return Response - */ - clone() { - return new Response(clone(this), { - url: this.url, - status: this.status, - statusText: this.statusText, - headers: this.headers, - ok: this.ok, - redirected: this.redirected - }); - } -} - -Body.mixIn(Response.prototype); - -Object.defineProperties(Response.prototype, { - url: { enumerable: true }, - status: { enumerable: true }, - ok: { enumerable: true }, - redirected: { enumerable: true }, - statusText: { enumerable: true }, - headers: { enumerable: true }, - clone: { enumerable: true } -}); - -Object.defineProperty(Response.prototype, Symbol.toStringTag, { - value: 'Response', - writable: false, - enumerable: false, - configurable: true -}); - -const INTERNALS$2 = Symbol('Request internals'); -const URL = Url.URL || whatwgUrl.URL; - -// fix an issue where "format", "parse" aren't a named export for node <10 -const parse_url = Url.parse; -const format_url = Url.format; - -/** - * Wrapper around `new URL` to handle arbitrary URLs + * @example + * ```ts + * import { FunctionsFetchError } from '@supabase/functions-js' * - * @param {string} urlStr - * @return {void} - */ -function parseURL(urlStr) { - /* - Check whether the URL is absolute or not - Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 - Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 + * throw new FunctionsFetchError({ requestId: 'abc123' }) + * ``` */ - if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { - urlStr = new URL(urlStr).toString(); - } - - // Fallback to old implementation for arbitrary URLs - return parse_url(urlStr); +class FunctionsFetchError extends FunctionsError { + constructor(context) { + super('Failed to send a request to the Edge Function', 'FunctionsFetchError', context); + } } - -const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; - +exports.FunctionsFetchError = FunctionsFetchError; /** - * Check if a value is an instance of Request. + * Error thrown when the Supabase relay cannot reach the Edge Function. * - * @param Mixed input - * @return Boolean + * @example + * ```ts + * import { FunctionsRelayError } from '@supabase/functions-js' + * + * throw new FunctionsRelayError({ region: 'us-east-1' }) + * ``` */ -function isRequest(input) { - return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; -} - -function isAbortSignal(signal) { - const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); - return !!(proto && proto.constructor.name === 'AbortSignal'); +class FunctionsRelayError extends FunctionsError { + constructor(context) { + super('Relay Error invoking the Edge Function', 'FunctionsRelayError', context); + } } - +exports.FunctionsRelayError = FunctionsRelayError; /** - * Request class + * Error thrown when the Edge Function returns a non-2xx status code. + * + * @example + * ```ts + * import { FunctionsHttpError } from '@supabase/functions-js' * - * @param Mixed input Url or Request instance - * @param Object init Custom options - * @return Void + * throw new FunctionsHttpError({ status: 500 }) + * ``` */ -class Request { - constructor(input) { - let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - let parsedURL; - - // normalize input - if (!isRequest(input)) { - if (input && input.href) { - // in order to support Node.js' Url objects; though WHATWG's URL objects - // will fall into this branch also (since their `toString()` will return - // `href` property anyway) - parsedURL = parseURL(input.href); - } else { - // coerce input to a string before attempting to parse - parsedURL = parseURL(`${input}`); - } - input = {}; - } else { - parsedURL = parseURL(input.url); - } - - let method = init.method || input.method || 'GET'; - method = method.toUpperCase(); +class FunctionsHttpError extends FunctionsError { + constructor(context) { + super('Edge Function returned a non-2xx status code', 'FunctionsHttpError', context); + } +} +exports.FunctionsHttpError = FunctionsHttpError; +// Define the enum for the 'region' property +var FunctionRegion; +(function (FunctionRegion) { + FunctionRegion["Any"] = "any"; + FunctionRegion["ApNortheast1"] = "ap-northeast-1"; + FunctionRegion["ApNortheast2"] = "ap-northeast-2"; + FunctionRegion["ApSouth1"] = "ap-south-1"; + FunctionRegion["ApSoutheast1"] = "ap-southeast-1"; + FunctionRegion["ApSoutheast2"] = "ap-southeast-2"; + FunctionRegion["CaCentral1"] = "ca-central-1"; + FunctionRegion["EuCentral1"] = "eu-central-1"; + FunctionRegion["EuWest1"] = "eu-west-1"; + FunctionRegion["EuWest2"] = "eu-west-2"; + FunctionRegion["EuWest3"] = "eu-west-3"; + FunctionRegion["SaEast1"] = "sa-east-1"; + FunctionRegion["UsEast1"] = "us-east-1"; + FunctionRegion["UsWest1"] = "us-west-1"; + FunctionRegion["UsWest2"] = "us-west-2"; +})(FunctionRegion || (exports.FunctionRegion = FunctionRegion = {})); +//# sourceMappingURL=types.js.map - if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { - throw new TypeError('Request with GET/HEAD method cannot have body'); - } +/***/ }), - let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; +/***/ 6479: +/***/ ((module) => { - Body.call(this, inputBody, { - timeout: init.timeout || input.timeout || 0, - size: init.size || input.size || 0 - }); - - const headers = new Headers(init.headers || input.headers || {}); - - if (inputBody != null && !headers.has('Content-Type')) { - const contentType = extractContentType(inputBody); - if (contentType) { - headers.append('Content-Type', contentType); - } - } - - let signal = isRequest(input) ? input.signal : null; - if ('signal' in init) signal = init.signal; - - if (signal != null && !isAbortSignal(signal)) { - throw new TypeError('Expected signal to be an instanceof AbortSignal'); - } - - this[INTERNALS$2] = { - method, - redirect: init.redirect || input.redirect || 'follow', - headers, - parsedURL, - signal - }; - - // node-fetch-only options - this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; - this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; - this.counter = init.counter || input.counter || 0; - this.agent = init.agent || input.agent; - } - - get method() { - return this[INTERNALS$2].method; - } - - get url() { - return format_url(this[INTERNALS$2].parsedURL); - } - - get headers() { - return this[INTERNALS$2].headers; - } - - get redirect() { - return this[INTERNALS$2].redirect; - } - - get signal() { - return this[INTERNALS$2].signal; - } - - /** - * Clone this request - * - * @return Request - */ - clone() { - return new Request(this); - } -} - -Body.mixIn(Request.prototype); - -Object.defineProperty(Request.prototype, Symbol.toStringTag, { - value: 'Request', - writable: false, - enumerable: false, - configurable: true -}); - -Object.defineProperties(Request.prototype, { - method: { enumerable: true }, - url: { enumerable: true }, - headers: { enumerable: true }, - redirect: { enumerable: true }, - clone: { enumerable: true }, - signal: { enumerable: true } -}); - -/** - * Convert a Request to Node.js http request options. - * - * @param Request A Request instance - * @return Object The options object to be passed to http.request - */ -function getNodeRequestOptions(request) { - const parsedURL = request[INTERNALS$2].parsedURL; - const headers = new Headers(request[INTERNALS$2].headers); - - // fetch step 1.3 - if (!headers.has('Accept')) { - headers.set('Accept', '*/*'); - } - - // Basic fetch - if (!parsedURL.protocol || !parsedURL.hostname) { - throw new TypeError('Only absolute URLs are supported'); - } - - if (!/^https?:$/.test(parsedURL.protocol)) { - throw new TypeError('Only HTTP(S) protocols are supported'); - } - - if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { - throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); - } - - // HTTP-network-or-cache fetch steps 2.4-2.7 - let contentLengthValue = null; - if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { - contentLengthValue = '0'; - } - if (request.body != null) { - const totalBytes = getTotalBytes(request); - if (typeof totalBytes === 'number') { - contentLengthValue = String(totalBytes); - } - } - if (contentLengthValue) { - headers.set('Content-Length', contentLengthValue); - } - - // HTTP-network-or-cache fetch step 2.11 - if (!headers.has('User-Agent')) { - headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); - } - - // HTTP-network-or-cache fetch step 2.15 - if (request.compress && !headers.has('Accept-Encoding')) { - headers.set('Accept-Encoding', 'gzip,deflate'); - } - - let agent = request.agent; - if (typeof agent === 'function') { - agent = agent(parsedURL); - } - - if (!headers.has('Connection') && !agent) { - headers.set('Connection', 'close'); - } - - // HTTP-network fetch step 4.2 - // chunked encoding is handled by Node.js - - return Object.assign({}, parsedURL, { - method: request.method, - headers: exportNodeCompatibleHeaders(headers), - agent - }); -} - -/** - * abort-error.js - * - * AbortError interface for cancelled requests - */ - -/** - * Create AbortError instance - * - * @param String message Error message for human - * @return AbortError - */ -function AbortError(message) { - Error.call(this, message); - - this.type = 'aborted'; - this.message = message; - - // hide custom error implementation details from end-users - Error.captureStackTrace(this, this.constructor); -} - -AbortError.prototype = Object.create(Error.prototype); -AbortError.prototype.constructor = AbortError; -AbortError.prototype.name = 'AbortError'; - -const URL$1 = Url.URL || whatwgUrl.URL; - -// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 -const PassThrough$1 = Stream.PassThrough; - -const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { - const orig = new URL$1(original).hostname; - const dest = new URL$1(destination).hostname; - - return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); -}; - -/** - * isSameProtocol reports whether the two provided URLs use the same protocol. - * - * Both domains must already be in canonical form. - * @param {string|URL} original - * @param {string|URL} destination - */ -const isSameProtocol = function isSameProtocol(destination, original) { - const orig = new URL$1(original).protocol; - const dest = new URL$1(destination).protocol; - - return orig === dest; -}; - -/** - * Fetch function - * - * @param Mixed url Absolute url or Request instance - * @param Object opts Fetch options - * @return Promise - */ -function fetch(url, opts) { - - // allow custom promise - if (!fetch.Promise) { - throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); - } - - Body.Promise = fetch.Promise; - - // wrap http.request into fetch - return new fetch.Promise(function (resolve, reject) { - // build request object - const request = new Request(url, opts); - const options = getNodeRequestOptions(request); - - const send = (options.protocol === 'https:' ? https : http).request; - const signal = request.signal; - - let response = null; - - const abort = function abort() { - let error = new AbortError('The user aborted a request.'); - reject(error); - if (request.body && request.body instanceof Stream.Readable) { - destroyStream(request.body, error); - } - if (!response || !response.body) return; - response.body.emit('error', error); - }; - - if (signal && signal.aborted) { - abort(); - return; - } - - const abortAndFinalize = function abortAndFinalize() { - abort(); - finalize(); - }; - - // send request - const req = send(options); - let reqTimeout; - - if (signal) { - signal.addEventListener('abort', abortAndFinalize); - } - - function finalize() { - req.abort(); - if (signal) signal.removeEventListener('abort', abortAndFinalize); - clearTimeout(reqTimeout); - } - - if (request.timeout) { - req.once('socket', function (socket) { - reqTimeout = setTimeout(function () { - reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); - finalize(); - }, request.timeout); - }); - } - - req.on('error', function (err) { - reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); - - if (response && response.body) { - destroyStream(response.body, err); - } - - finalize(); - }); - - fixResponseChunkedTransferBadEnding(req, function (err) { - if (signal && signal.aborted) { - return; - } - - if (response && response.body) { - destroyStream(response.body, err); - } - }); - - /* c8 ignore next 18 */ - if (parseInt(process.version.substring(1)) < 14) { - // Before Node.js 14, pipeline() does not fully support async iterators and does not always - // properly handle when the socket close/end events are out of order. - req.on('socket', function (s) { - s.addListener('close', function (hadError) { - // if a data listener is still present we didn't end cleanly - const hasDataListener = s.listenerCount('data') > 0; - - // if end happened before close but the socket didn't emit an error, do it now - if (response && hasDataListener && !hadError && !(signal && signal.aborted)) { - const err = new Error('Premature close'); - err.code = 'ERR_STREAM_PREMATURE_CLOSE'; - response.body.emit('error', err); - } - }); - }); - } - - req.on('response', function (res) { - clearTimeout(reqTimeout); - - const headers = createHeadersLenient(res.headers); - - // HTTP fetch step 5 - if (fetch.isRedirect(res.statusCode)) { - // HTTP fetch step 5.2 - const location = headers.get('Location'); - - // HTTP fetch step 5.3 - let locationURL = null; - try { - locationURL = location === null ? null : new URL$1(location, request.url).toString(); - } catch (err) { - // error here can only be invalid URL in Location: header - // do not throw when options.redirect == manual - // let the user extract the errorneous redirect URL - if (request.redirect !== 'manual') { - reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); - finalize(); - return; - } - } - - // HTTP fetch step 5.5 - switch (request.redirect) { - case 'error': - reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); - finalize(); - return; - case 'manual': - // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. - if (locationURL !== null) { - // handle corrupted header - try { - headers.set('Location', locationURL); - } catch (err) { - // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request - reject(err); - } - } - break; - case 'follow': - // HTTP-redirect fetch step 2 - if (locationURL === null) { - break; - } - - // HTTP-redirect fetch step 5 - if (request.counter >= request.follow) { - reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); - finalize(); - return; - } - - // HTTP-redirect fetch step 6 (counter increment) - // Create a new Request object. - const requestOpts = { - headers: new Headers(request.headers), - follow: request.follow, - counter: request.counter + 1, - agent: request.agent, - compress: request.compress, - method: request.method, - body: request.body, - signal: request.signal, - timeout: request.timeout, - size: request.size - }; - - if (!isDomainOrSubdomain(request.url, locationURL) || !isSameProtocol(request.url, locationURL)) { - for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { - requestOpts.headers.delete(name); - } - } - - // HTTP-redirect fetch step 9 - if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { - reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); - finalize(); - return; - } - - // HTTP-redirect fetch step 11 - if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { - requestOpts.method = 'GET'; - requestOpts.body = undefined; - requestOpts.headers.delete('content-length'); - } - - // HTTP-redirect fetch step 15 - resolve(fetch(new Request(locationURL, requestOpts))); - finalize(); - return; - } - } - - // prepare response - res.once('end', function () { - if (signal) signal.removeEventListener('abort', abortAndFinalize); - }); - let body = res.pipe(new PassThrough$1()); - - const response_options = { - url: request.url, - status: res.statusCode, - statusText: res.statusMessage, - headers: headers, - size: request.size, - timeout: request.timeout, - counter: request.counter - }; - - // HTTP-network fetch step 12.1.1.3 - const codings = headers.get('Content-Encoding'); - - // HTTP-network fetch step 12.1.1.4: handle content codings - - // in following scenarios we ignore compression support - // 1. compression support is disabled - // 2. HEAD request - // 3. no Content-Encoding header - // 4. no content response (204) - // 5. content not modified response (304) - if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { - response = new Response(body, response_options); - resolve(response); - return; - } - - // For Node v6+ - // Be less strict when decoding compressed responses, since sometimes - // servers send slightly invalid responses that are still accepted - // by common browsers. - // Always using Z_SYNC_FLUSH is what cURL does. - const zlibOptions = { - flush: zlib.Z_SYNC_FLUSH, - finishFlush: zlib.Z_SYNC_FLUSH - }; - - // for gzip - if (codings == 'gzip' || codings == 'x-gzip') { - body = body.pipe(zlib.createGunzip(zlibOptions)); - response = new Response(body, response_options); - resolve(response); - return; - } - - // for deflate - if (codings == 'deflate' || codings == 'x-deflate') { - // handle the infamous raw deflate response from old servers - // a hack for old IIS and Apache servers - const raw = res.pipe(new PassThrough$1()); - raw.once('data', function (chunk) { - // see http://stackoverflow.com/questions/37519828 - if ((chunk[0] & 0x0F) === 0x08) { - body = body.pipe(zlib.createInflate()); - } else { - body = body.pipe(zlib.createInflateRaw()); - } - response = new Response(body, response_options); - resolve(response); - }); - raw.on('end', function () { - // some old IIS servers return zero-length OK deflate responses, so 'data' is never emitted. - if (!response) { - response = new Response(body, response_options); - resolve(response); - } - }); - return; - } - - // for br - if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { - body = body.pipe(zlib.createBrotliDecompress()); - response = new Response(body, response_options); - resolve(response); - return; - } - - // otherwise, use response as-is - response = new Response(body, response_options); - resolve(response); - }); - - writeToStream(req, request); - }); -} -function fixResponseChunkedTransferBadEnding(request, errorCallback) { - let socket; - - request.on('socket', function (s) { - socket = s; - }); - - request.on('response', function (response) { - const headers = response.headers; - - if (headers['transfer-encoding'] === 'chunked' && !headers['content-length']) { - response.once('close', function (hadError) { - // tests for socket presence, as in some situations the - // the 'socket' event is not triggered for the request - // (happens in deno), avoids `TypeError` - // if a data listener is still present we didn't end cleanly - const hasDataListener = socket && socket.listenerCount('data') > 0; - - if (hasDataListener && !hadError) { - const err = new Error('Premature close'); - err.code = 'ERR_STREAM_PREMATURE_CLOSE'; - errorCallback(err); - } - }); - } - }); -} - -function destroyStream(stream, err) { - if (stream.destroy) { - stream.destroy(err); - } else { - // node < 8 - stream.emit('error', err); - stream.end(); - } -} - -/** - * Redirect code matching - * - * @param Number code Status code - * @return Boolean - */ -fetch.isRedirect = function (code) { - return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; -}; - -// expose Promise -fetch.Promise = global.Promise; - -module.exports = exports = fetch; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = exports; -exports.Headers = Headers; -exports.Request = Request; -exports.Response = Response; -exports.FetchError = FetchError; +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +/* global global, define, Symbol, Reflect, Promise, SuppressedError, Iterator */ +var __extends; +var __assign; +var __rest; +var __decorate; +var __param; +var __esDecorate; +var __runInitializers; +var __propKey; +var __setFunctionName; +var __metadata; +var __awaiter; +var __generator; +var __exportStar; +var __values; +var __read; +var __spread; +var __spreadArrays; +var __spreadArray; +var __await; +var __asyncGenerator; +var __asyncDelegator; +var __asyncValues; +var __makeTemplateObject; +var __importStar; +var __importDefault; +var __classPrivateFieldGet; +var __classPrivateFieldSet; +var __classPrivateFieldIn; +var __createBinding; +var __addDisposableResource; +var __disposeResources; +var __rewriteRelativeImportExtension; +(function (factory) { + var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {}; + if (typeof define === "function" && define.amd) { + define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); }); + } + else if ( true && typeof module.exports === "object") { + factory(createExporter(root, createExporter(module.exports))); + } + else { + factory(createExporter(root)); + } + function createExporter(exports, previous) { + if (exports !== root) { + if (typeof Object.create === "function") { + Object.defineProperty(exports, "__esModule", { value: true }); + } + else { + exports.__esModule = true; + } + } + return function (id, v) { return exports[id] = previous ? previous(id, v) : v; }; + } +}) +(function (exporter) { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + + __extends = function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; + + __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; + }; + + __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; + }; + + __decorate = function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + 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; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + + __param = function (paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } + }; + + __esDecorate = function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; + }; + + __runInitializers = function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; + }; + + __propKey = function (x) { + return typeof x === "symbol" ? x : "".concat(x); + }; + + __setFunctionName = function (f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); + }; + + __metadata = function (metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); + }; + + __awaiter = function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + + __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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); + return g.next = verb(0), g["throw"] = verb(1), g["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 (g && (g = 0, op[0] && (_ = 0)), _) 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 }; + } + }; + + __exportStar = function(m, o) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); + }; + + __createBinding = Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + }); + + __values = function (o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + }; + + __read = function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; + }; + + /** @deprecated */ + __spread = function () { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; + }; + + /** @deprecated */ + __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; + }; + + __spreadArray = function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); + }; + + __await = function (v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); + }; + + __asyncGenerator = function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; + function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } + function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } + }; + + __asyncDelegator = function (o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; + function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } + }; + + __asyncValues = function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + 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); + 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); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } + }; + + __makeTemplateObject = function (cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; + }; + + var __setModuleDefault = Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }; + + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + + __importStar = function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; + + __importDefault = function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + + __classPrivateFieldGet = function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); + }; + + __classPrivateFieldSet = function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; + }; + + __classPrivateFieldIn = function (state, receiver) { + if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); + return typeof state === "function" ? receiver === state : state.has(receiver); + }; + + __addDisposableResource = function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose, inner; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + if (async) inner = dispose; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } }; + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; + }; + + var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; + }; + + __disposeResources = function (env) { + function fail(e) { + env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + var r, s = 0; + function next() { + while (r = env.stack.pop()) { + try { + if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); + if (r.dispose) { + var result = r.dispose.call(r.value); + if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + else s |= 1; + } + catch (e) { + fail(e); + } + } + if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); + if (env.hasError) throw env.error; + } + return next(); + }; + + __rewriteRelativeImportExtension = function (path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); + } + return path; + }; + + exporter("__extends", __extends); + exporter("__assign", __assign); + exporter("__rest", __rest); + exporter("__decorate", __decorate); + exporter("__param", __param); + exporter("__esDecorate", __esDecorate); + exporter("__runInitializers", __runInitializers); + exporter("__propKey", __propKey); + exporter("__setFunctionName", __setFunctionName); + exporter("__metadata", __metadata); + exporter("__awaiter", __awaiter); + exporter("__generator", __generator); + exporter("__exportStar", __exportStar); + exporter("__createBinding", __createBinding); + exporter("__values", __values); + exporter("__read", __read); + exporter("__spread", __spread); + exporter("__spreadArrays", __spreadArrays); + exporter("__spreadArray", __spreadArray); + exporter("__await", __await); + exporter("__asyncGenerator", __asyncGenerator); + exporter("__asyncDelegator", __asyncDelegator); + exporter("__asyncValues", __asyncValues); + exporter("__makeTemplateObject", __makeTemplateObject); + exporter("__importStar", __importStar); + exporter("__importDefault", __importDefault); + exporter("__classPrivateFieldGet", __classPrivateFieldGet); + exporter("__classPrivateFieldSet", __classPrivateFieldSet); + exporter("__classPrivateFieldIn", __classPrivateFieldIn); + exporter("__addDisposableResource", __addDisposableResource); + exporter("__disposeResources", __disposeResources); + exporter("__rewriteRelativeImportExtension", __rewriteRelativeImportExtension); +}); + +0 && (0); /***/ }), -/***/ 9963: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 9911: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -// @ts-ignore -const node_fetch_1 = __importDefault(__nccwpck_require__(2668)); -class PostgrestBuilder { - constructor(builder) { - this.shouldThrowOnError = false; - this.method = builder.method; - this.url = builder.url; - this.headers = builder.headers; - this.schema = builder.schema; - this.body = builder.body; - this.shouldThrowOnError = builder.shouldThrowOnError; - this.signal = builder.signal; - this.isMaybeSingle = builder.isMaybeSingle; - if (builder.fetch) { - this.fetch = builder.fetch; - } - else if (typeof fetch === 'undefined') { - this.fetch = node_fetch_1.default; - } - else { - this.fetch = fetch; - } - } +exports.REALTIME_CHANNEL_STATES = exports.REALTIME_SUBSCRIBE_STATES = exports.REALTIME_LISTEN_TYPES = exports.REALTIME_POSTGRES_CHANGES_LISTEN_EVENT = void 0; +const tslib_1 = __nccwpck_require__(7647); +const constants_1 = __nccwpck_require__(88); +const push_1 = tslib_1.__importDefault(__nccwpck_require__(2292)); +const timer_1 = tslib_1.__importDefault(__nccwpck_require__(2983)); +const RealtimePresence_1 = tslib_1.__importDefault(__nccwpck_require__(5583)); +const Transformers = tslib_1.__importStar(__nccwpck_require__(1140)); +const transformers_1 = __nccwpck_require__(1140); +var REALTIME_POSTGRES_CHANGES_LISTEN_EVENT; +(function (REALTIME_POSTGRES_CHANGES_LISTEN_EVENT) { + REALTIME_POSTGRES_CHANGES_LISTEN_EVENT["ALL"] = "*"; + REALTIME_POSTGRES_CHANGES_LISTEN_EVENT["INSERT"] = "INSERT"; + REALTIME_POSTGRES_CHANGES_LISTEN_EVENT["UPDATE"] = "UPDATE"; + REALTIME_POSTGRES_CHANGES_LISTEN_EVENT["DELETE"] = "DELETE"; +})(REALTIME_POSTGRES_CHANGES_LISTEN_EVENT || (exports.REALTIME_POSTGRES_CHANGES_LISTEN_EVENT = REALTIME_POSTGRES_CHANGES_LISTEN_EVENT = {})); +var REALTIME_LISTEN_TYPES; +(function (REALTIME_LISTEN_TYPES) { + REALTIME_LISTEN_TYPES["BROADCAST"] = "broadcast"; + REALTIME_LISTEN_TYPES["PRESENCE"] = "presence"; + REALTIME_LISTEN_TYPES["POSTGRES_CHANGES"] = "postgres_changes"; + REALTIME_LISTEN_TYPES["SYSTEM"] = "system"; +})(REALTIME_LISTEN_TYPES || (exports.REALTIME_LISTEN_TYPES = REALTIME_LISTEN_TYPES = {})); +var REALTIME_SUBSCRIBE_STATES; +(function (REALTIME_SUBSCRIBE_STATES) { + REALTIME_SUBSCRIBE_STATES["SUBSCRIBED"] = "SUBSCRIBED"; + REALTIME_SUBSCRIBE_STATES["TIMED_OUT"] = "TIMED_OUT"; + REALTIME_SUBSCRIBE_STATES["CLOSED"] = "CLOSED"; + REALTIME_SUBSCRIBE_STATES["CHANNEL_ERROR"] = "CHANNEL_ERROR"; +})(REALTIME_SUBSCRIBE_STATES || (exports.REALTIME_SUBSCRIBE_STATES = REALTIME_SUBSCRIBE_STATES = {})); +exports.REALTIME_CHANNEL_STATES = constants_1.CHANNEL_STATES; +/** A channel is the basic building block of Realtime + * and narrows the scope of data flow to subscribed clients. + * You can think of a channel as a chatroom where participants are able to see who's online + * and send and receive messages. + */ +class RealtimeChannel { /** - * If there's an error with the query, throwOnError will reject the promise by - * throwing the error instead of returning it as part of a successful response. + * Creates a channel that can broadcast messages, sync presence, and listen to Postgres changes. * - * {@link https://github.com/supabase/supabase-js/issues/92} + * The topic determines which realtime stream you are subscribing to. Config options let you + * enable acknowledgement for broadcasts, presence tracking, or private channels. + * + * @example + * ```ts + * import RealtimeClient from '@supabase/realtime-js' + * + * const client = new RealtimeClient('https://xyzcompany.supabase.co/realtime/v1', { + * params: { apikey: 'public-anon-key' }, + * }) + * const channel = new RealtimeChannel('realtime:public:messages', { config: {} }, client) + * ``` */ - throwOnError() { - this.shouldThrowOnError = true; - return this; - } - then(onfulfilled, onrejected) { - // https://postgrest.org/en/stable/api.html#switching-schemas - if (this.schema === undefined) { - // skip - } - else if (['GET', 'HEAD'].includes(this.method)) { - this.headers['Accept-Profile'] = this.schema; - } - else { - this.headers['Content-Profile'] = this.schema; + constructor( + /** Topic name can be any string. */ + topic, params = { config: {} }, socket) { + var _a, _b; + this.topic = topic; + this.params = params; + this.socket = socket; + this.bindings = {}; + this.state = constants_1.CHANNEL_STATES.closed; + this.joinedOnce = false; + this.pushBuffer = []; + this.subTopic = topic.replace(/^realtime:/i, ''); + this.params.config = Object.assign({ + broadcast: { ack: false, self: false }, + presence: { key: '', enabled: false }, + private: false, + }, params.config); + this.timeout = this.socket.timeout; + this.joinPush = new push_1.default(this, constants_1.CHANNEL_EVENTS.join, this.params, this.timeout); + this.rejoinTimer = new timer_1.default(() => this._rejoinUntilConnected(), this.socket.reconnectAfterMs); + this.joinPush.receive('ok', () => { + this.state = constants_1.CHANNEL_STATES.joined; + this.rejoinTimer.reset(); + this.pushBuffer.forEach((pushEvent) => pushEvent.send()); + this.pushBuffer = []; + }); + this._onClose(() => { + this.rejoinTimer.reset(); + this.socket.log('channel', `close ${this.topic} ${this._joinRef()}`); + this.state = constants_1.CHANNEL_STATES.closed; + this.socket._remove(this); + }); + this._onError((reason) => { + if (this._isLeaving() || this._isClosed()) { + return; + } + this.socket.log('channel', `error ${this.topic}`, reason); + this.state = constants_1.CHANNEL_STATES.errored; + this.rejoinTimer.scheduleTimeout(); + }); + this.joinPush.receive('timeout', () => { + if (!this._isJoining()) { + return; + } + this.socket.log('channel', `timeout ${this.topic}`, this.joinPush.timeout); + this.state = constants_1.CHANNEL_STATES.errored; + this.rejoinTimer.scheduleTimeout(); + }); + this.joinPush.receive('error', (reason) => { + if (this._isLeaving() || this._isClosed()) { + return; + } + this.socket.log('channel', `error ${this.topic}`, reason); + this.state = constants_1.CHANNEL_STATES.errored; + this.rejoinTimer.scheduleTimeout(); + }); + this._on(constants_1.CHANNEL_EVENTS.reply, {}, (payload, ref) => { + this._trigger(this._replyEventName(ref), payload); + }); + this.presence = new RealtimePresence_1.default(this); + this.broadcastEndpointURL = (0, transformers_1.httpEndpointURL)(this.socket.endPoint); + this.private = this.params.config.private || false; + if (!this.private && ((_b = (_a = this.params.config) === null || _a === void 0 ? void 0 : _a.broadcast) === null || _b === void 0 ? void 0 : _b.replay)) { + throw `tried to use replay on public channel '${this.topic}'. It must be a private channel.`; } - if (this.method !== 'GET' && this.method !== 'HEAD') { - this.headers['Content-Type'] = 'application/json'; + } + /** Subscribe registers your client with the server */ + subscribe(callback, timeout = this.timeout) { + var _a, _b, _c; + if (!this.socket.isConnected()) { + this.socket.connect(); } - // NOTE: Invoke w/o `this` to avoid illegal invocation error. - // https://github.com/supabase/postgrest-js/pull/247 - const _fetch = this.fetch; - let res = _fetch(this.url.toString(), { - method: this.method, - headers: this.headers, - body: JSON.stringify(this.body), - signal: this.signal, - }).then(async (res) => { - var _a, _b, _c; - let error = null; - let data = null; - let count = null; - let status = res.status; - let statusText = res.statusText; - if (res.ok) { - if (this.method !== 'HEAD') { - const body = await res.text(); - if (body === '') { - // Prefer: return=minimal - } - else if (this.headers['Accept'] === 'text/csv') { - data = body; - } - else if (this.headers['Accept'] && - this.headers['Accept'].includes('application/vnd.pgrst.plan+text')) { - data = body; - } - else { - data = JSON.parse(body); - } - } - const countHeader = (_a = this.headers['Prefer']) === null || _a === void 0 ? void 0 : _a.match(/count=(exact|planned|estimated)/); - const contentRange = (_b = res.headers.get('content-range')) === null || _b === void 0 ? void 0 : _b.split('/'); - if (countHeader && contentRange && contentRange.length > 1) { - count = parseInt(contentRange[1]); - } - // Temporary partial fix for https://github.com/supabase/postgrest-js/issues/361 - // Issue persists e.g. for `.insert([...]).select().maybeSingle()` - if (this.isMaybeSingle && this.method === 'GET' && Array.isArray(data)) { - if (data.length > 1) { - error = { - // https://github.com/PostgREST/postgrest/blob/a867d79c42419af16c18c3fb019eba8df992626f/src/PostgREST/Error.hs#L553 - code: 'PGRST116', - details: `Results contain ${data.length} rows, application/vnd.pgrst.object+json requires 1 row`, - hint: null, - message: 'JSON object requested, multiple (or no) rows returned', - }; - data = null; - count = null; - status = 406; - statusText = 'Not Acceptable'; - } - else if (data.length === 1) { - data = data[0]; - } - else { - data = null; - } - } + if (this.state == constants_1.CHANNEL_STATES.closed) { + const { config: { broadcast, presence, private: isPrivate }, } = this.params; + const postgres_changes = (_b = (_a = this.bindings.postgres_changes) === null || _a === void 0 ? void 0 : _a.map((r) => r.filter)) !== null && _b !== void 0 ? _b : []; + const presence_enabled = (!!this.bindings[REALTIME_LISTEN_TYPES.PRESENCE] && + this.bindings[REALTIME_LISTEN_TYPES.PRESENCE].length > 0) || + ((_c = this.params.config.presence) === null || _c === void 0 ? void 0 : _c.enabled) === true; + const accessTokenPayload = {}; + const config = { + broadcast, + presence: Object.assign(Object.assign({}, presence), { enabled: presence_enabled }), + postgres_changes, + private: isPrivate, + }; + if (this.socket.accessTokenValue) { + accessTokenPayload.access_token = this.socket.accessTokenValue; } - else { - const body = await res.text(); - try { - error = JSON.parse(body); - // Workaround for https://github.com/supabase/postgrest-js/issues/295 - if (Array.isArray(error) && res.status === 404) { - data = []; - error = null; - status = 200; - statusText = 'OK'; - } - } - catch (_d) { - // Workaround for https://github.com/supabase/postgrest-js/issues/295 - if (res.status === 404 && body === '') { - status = 204; - statusText = 'No Content'; - } - else { - error = { - message: body, - }; - } + this._onError((e) => callback === null || callback === void 0 ? void 0 : callback(REALTIME_SUBSCRIBE_STATES.CHANNEL_ERROR, e)); + this._onClose(() => callback === null || callback === void 0 ? void 0 : callback(REALTIME_SUBSCRIBE_STATES.CLOSED)); + this.updateJoinPayload(Object.assign({ config }, accessTokenPayload)); + this.joinedOnce = true; + this._rejoin(timeout); + this.joinPush + .receive('ok', async ({ postgres_changes }) => { + var _a; + // Only refresh auth if using callback-based tokens + if (!this.socket._isManualToken()) { + this.socket.setAuth(); } - if (error && this.isMaybeSingle && ((_c = error === null || error === void 0 ? void 0 : error.details) === null || _c === void 0 ? void 0 : _c.includes('0 rows'))) { - error = null; - status = 200; - statusText = 'OK'; + if (postgres_changes === undefined) { + callback === null || callback === void 0 ? void 0 : callback(REALTIME_SUBSCRIBE_STATES.SUBSCRIBED); + return; } - if (error && this.shouldThrowOnError) { - throw error; + else { + const clientPostgresBindings = this.bindings.postgres_changes; + const bindingsLen = (_a = clientPostgresBindings === null || clientPostgresBindings === void 0 ? void 0 : clientPostgresBindings.length) !== null && _a !== void 0 ? _a : 0; + const newPostgresBindings = []; + for (let i = 0; i < bindingsLen; i++) { + const clientPostgresBinding = clientPostgresBindings[i]; + const { filter: { event, schema, table, filter }, } = clientPostgresBinding; + const serverPostgresFilter = postgres_changes && postgres_changes[i]; + if (serverPostgresFilter && + serverPostgresFilter.event === event && + RealtimeChannel.isFilterValueEqual(serverPostgresFilter.schema, schema) && + RealtimeChannel.isFilterValueEqual(serverPostgresFilter.table, table) && + RealtimeChannel.isFilterValueEqual(serverPostgresFilter.filter, filter)) { + newPostgresBindings.push(Object.assign(Object.assign({}, clientPostgresBinding), { id: serverPostgresFilter.id })); + } + else { + this.unsubscribe(); + this.state = constants_1.CHANNEL_STATES.errored; + callback === null || callback === void 0 ? void 0 : callback(REALTIME_SUBSCRIBE_STATES.CHANNEL_ERROR, new Error('mismatch between server and client bindings for postgres changes')); + return; + } + } + this.bindings.postgres_changes = newPostgresBindings; + callback && callback(REALTIME_SUBSCRIBE_STATES.SUBSCRIBED); + return; } - } - const postgrestResponse = { - error, - data, - count, - status, - statusText, - }; - return postgrestResponse; - }); - if (!this.shouldThrowOnError) { - res = res.catch((fetchError) => { - var _a, _b, _c; - return ({ - error: { - message: `${(_a = fetchError === null || fetchError === void 0 ? void 0 : fetchError.name) !== null && _a !== void 0 ? _a : 'FetchError'}: ${fetchError === null || fetchError === void 0 ? void 0 : fetchError.message}`, - details: `${(_b = fetchError === null || fetchError === void 0 ? void 0 : fetchError.stack) !== null && _b !== void 0 ? _b : ''}`, - hint: '', - code: `${(_c = fetchError === null || fetchError === void 0 ? void 0 : fetchError.code) !== null && _c !== void 0 ? _c : ''}`, - }, - data: null, - count: null, - status: 0, - statusText: '', - }); + }) + .receive('error', (error) => { + this.state = constants_1.CHANNEL_STATES.errored; + callback === null || callback === void 0 ? void 0 : callback(REALTIME_SUBSCRIBE_STATES.CHANNEL_ERROR, new Error(JSON.stringify(Object.values(error).join(', ') || 'error'))); + return; + }) + .receive('timeout', () => { + callback === null || callback === void 0 ? void 0 : callback(REALTIME_SUBSCRIBE_STATES.TIMED_OUT); + return; }); } - return res.then(onfulfilled, onrejected); + return this; } -} -exports["default"] = PostgrestBuilder; -//# sourceMappingURL=PostgrestBuilder.js.map - -/***/ }), - -/***/ 8223: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -const PostgrestQueryBuilder_1 = __importDefault(__nccwpck_require__(5683)); -const PostgrestFilterBuilder_1 = __importDefault(__nccwpck_require__(1446)); -const constants_1 = __nccwpck_require__(879); -/** - * PostgREST client. - * - * @typeParam Database - Types for the schema from the [type - * generator](https://supabase.com/docs/reference/javascript/next/typescript-support) - * - * @typeParam SchemaName - Postgres schema to switch to. Must be a string - * literal, the same one passed to the constructor. If the schema is not - * `"public"`, this must be supplied manually. - */ -class PostgrestClient { - // TODO: Add back shouldThrowOnError once we figure out the typings /** - * Creates a PostgREST client. + * Returns the current presence state for this channel. * - * @param url - URL of the PostgREST endpoint - * @param options - Named parameters - * @param options.headers - Custom headers - * @param options.schema - Postgres schema to switch to - * @param options.fetch - Custom fetch + * The shape is a map keyed by presence key (for example a user id) where each entry contains the + * tracked metadata for that user. */ - constructor(url, { headers = {}, schema, fetch, } = {}) { - this.url = url; - this.headers = Object.assign(Object.assign({}, constants_1.DEFAULT_HEADERS), headers); - this.schemaName = schema; - this.fetch = fetch; + presenceState() { + return this.presence.state; } /** - * Perform a query on a table or a view. - * - * @param relation - The table or view name to query + * Sends the supplied payload to the presence tracker so other subscribers can see that this + * client is online. Use `untrack` to stop broadcasting presence for the same key. */ - from(relation) { - const url = new URL(`${this.url}/${relation}`); - return new PostgrestQueryBuilder_1.default(url, { - headers: Object.assign({}, this.headers), - schema: this.schemaName, - fetch: this.fetch, - }); + async track(payload, opts = {}) { + return await this.send({ + type: 'presence', + event: 'track', + payload, + }, opts.timeout || this.timeout); } /** - * Select a schema to query or perform an function (rpc) call. - * - * The schema needs to be on the list of exposed schemas inside Supabase. - * - * @param schema - The schema to query + * Removes the current presence state for this client. */ - schema(schema) { - return new PostgrestClient(this.url, { - headers: this.headers, - schema, - fetch: this.fetch, - }); + async untrack(opts = {}) { + return await this.send({ + type: 'presence', + event: 'untrack', + }, opts); + } + on(type, filter, callback) { + if (this.state === constants_1.CHANNEL_STATES.joined && type === REALTIME_LISTEN_TYPES.PRESENCE) { + this.socket.log('channel', `resubscribe to ${this.topic} due to change in presence callbacks on joined channel`); + this.unsubscribe().then(async () => await this.subscribe()); + } + return this._on(type, filter, callback); } /** - * Perform a function call. - * - * @param fn - The function name to call - * @param args - The arguments to pass to the function call - * @param options - Named parameters - * @param options.head - When set to `true`, `data` will not be returned. - * Useful if you only need the count. - * @param options.count - Count algorithm to use to count rows returned by the - * function. Only applicable for [set-returning - * functions](https://www.postgresql.org/docs/current/functions-srf.html). + * Sends a broadcast message explicitly via REST API. * - * `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the - * hood. + * This method always uses the REST API endpoint regardless of WebSocket connection state. + * Useful when you want to guarantee REST delivery or when gradually migrating from implicit REST fallback. * - * `"planned"`: Approximated but fast count algorithm. Uses the Postgres - * statistics under the hood. - * - * `"estimated"`: Uses exact count for low numbers and planned count for high - * numbers. + * @param event The name of the broadcast event + * @param payload Payload to be sent (required) + * @param opts Options including timeout + * @returns Promise resolving to object with success status, and error details if failed */ - rpc(fn, args = {}, { head = false, count, } = {}) { - let method; - const url = new URL(`${this.url}/rpc/${fn}`); - let body; - if (head) { - method = 'HEAD'; - Object.entries(args).forEach(([name, value]) => { - url.searchParams.append(name, `${value}`); - }); - } - else { - method = 'POST'; - body = args; + async httpSend(event, payload, opts = {}) { + var _a; + if (payload === undefined || payload === null) { + return Promise.reject('Payload is required for httpSend()'); } - const headers = Object.assign({}, this.headers); - if (count) { - headers['Prefer'] = `count=${count}`; + const headers = { + apikey: this.socket.apiKey ? this.socket.apiKey : '', + 'Content-Type': 'application/json', + }; + if (this.socket.accessTokenValue) { + headers['Authorization'] = `Bearer ${this.socket.accessTokenValue}`; } - return new PostgrestFilterBuilder_1.default({ - method, - url, + const options = { + method: 'POST', headers, - schema: this.schemaName, - body, - fetch: this.fetch, - allowEmpty: false, - }); + body: JSON.stringify({ + messages: [ + { + topic: this.subTopic, + event, + payload: payload, + private: this.private, + }, + ], + }), + }; + const response = await this._fetchWithTimeout(this.broadcastEndpointURL, options, (_a = opts.timeout) !== null && _a !== void 0 ? _a : this.timeout); + if (response.status === 202) { + return { success: true }; + } + let errorMessage = response.statusText; + try { + const errorBody = await response.json(); + errorMessage = errorBody.error || errorBody.message || errorMessage; + } + catch (_b) { } + return Promise.reject(new Error(errorMessage)); } -} -exports["default"] = PostgrestClient; -//# sourceMappingURL=PostgrestClient.js.map - -/***/ }), - -/***/ 1446: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -const PostgrestTransformBuilder_1 = __importDefault(__nccwpck_require__(39)); -class PostgrestFilterBuilder extends PostgrestTransformBuilder_1.default { /** - * Match only rows where `column` is equal to `value`. - * - * To check if the value of `column` is NULL, you should use `.is()` instead. + * Sends a message into the channel. * - * @param column - The column to filter on - * @param value - The value to filter with + * @param args Arguments to send to channel + * @param args.type The type of event to send + * @param args.event The name of the event being sent + * @param args.payload Payload to be sent + * @param opts Options to be used during the send process */ - eq(column, value) { - this.url.searchParams.append(column, `eq.${value}`); - return this; + async send(args, opts = {}) { + var _a, _b; + if (!this._canPush() && args.type === 'broadcast') { + console.warn('Realtime send() is automatically falling back to REST API. ' + + 'This behavior will be deprecated in the future. ' + + 'Please use httpSend() explicitly for REST delivery.'); + const { event, payload: endpoint_payload } = args; + const headers = { + apikey: this.socket.apiKey ? this.socket.apiKey : '', + 'Content-Type': 'application/json', + }; + if (this.socket.accessTokenValue) { + headers['Authorization'] = `Bearer ${this.socket.accessTokenValue}`; + } + const options = { + method: 'POST', + headers, + body: JSON.stringify({ + messages: [ + { + topic: this.subTopic, + event, + payload: endpoint_payload, + private: this.private, + }, + ], + }), + }; + try { + const response = await this._fetchWithTimeout(this.broadcastEndpointURL, options, (_a = opts.timeout) !== null && _a !== void 0 ? _a : this.timeout); + await ((_b = response.body) === null || _b === void 0 ? void 0 : _b.cancel()); + return response.ok ? 'ok' : 'error'; + } + catch (error) { + if (error.name === 'AbortError') { + return 'timed out'; + } + else { + return 'error'; + } + } + } + else { + return new Promise((resolve) => { + var _a, _b, _c; + const push = this._push(args.type, args, opts.timeout || this.timeout); + if (args.type === 'broadcast' && !((_c = (_b = (_a = this.params) === null || _a === void 0 ? void 0 : _a.config) === null || _b === void 0 ? void 0 : _b.broadcast) === null || _c === void 0 ? void 0 : _c.ack)) { + resolve('ok'); + } + push.receive('ok', () => resolve('ok')); + push.receive('error', () => resolve('error')); + push.receive('timeout', () => resolve('timed out')); + }); + } } /** - * Match only rows where `column` is not equal to `value`. - * - * @param column - The column to filter on - * @param value - The value to filter with + * Updates the payload that will be sent the next time the channel joins (reconnects). + * Useful for rotating access tokens or updating config without re-creating the channel. */ - neq(column, value) { - this.url.searchParams.append(column, `neq.${value}`); - return this; + updateJoinPayload(payload) { + this.joinPush.updatePayload(payload); } /** - * Match only rows where `column` is greater than `value`. + * Leaves the channel. * - * @param column - The column to filter on - * @param value - The value to filter with - */ - gt(column, value) { - this.url.searchParams.append(column, `gt.${value}`); - return this; - } - /** - * Match only rows where `column` is greater than or equal to `value`. + * Unsubscribes from server events, and instructs channel to terminate on server. + * Triggers onClose() hooks. * - * @param column - The column to filter on - * @param value - The value to filter with + * To receive leave acknowledgements, use the a `receive` hook to bind to the server ack, ie: + * channel.unsubscribe().receive("ok", () => alert("left!") ) */ - gte(column, value) { - this.url.searchParams.append(column, `gte.${value}`); - return this; + unsubscribe(timeout = this.timeout) { + this.state = constants_1.CHANNEL_STATES.leaving; + const onClose = () => { + this.socket.log('channel', `leave ${this.topic}`); + this._trigger(constants_1.CHANNEL_EVENTS.close, 'leave', this._joinRef()); + }; + this.joinPush.destroy(); + let leavePush = null; + return new Promise((resolve) => { + leavePush = new push_1.default(this, constants_1.CHANNEL_EVENTS.leave, {}, timeout); + leavePush + .receive('ok', () => { + onClose(); + resolve('ok'); + }) + .receive('timeout', () => { + onClose(); + resolve('timed out'); + }) + .receive('error', () => { + resolve('error'); + }); + leavePush.send(); + if (!this._canPush()) { + leavePush.trigger('ok', {}); + } + }).finally(() => { + leavePush === null || leavePush === void 0 ? void 0 : leavePush.destroy(); + }); } /** - * Match only rows where `column` is less than `value`. + * Teardown the channel. * - * @param column - The column to filter on - * @param value - The value to filter with + * Destroys and stops related timers. */ - lt(column, value) { - this.url.searchParams.append(column, `lt.${value}`); - return this; + teardown() { + this.pushBuffer.forEach((push) => push.destroy()); + this.pushBuffer = []; + this.rejoinTimer.reset(); + this.joinPush.destroy(); + this.state = constants_1.CHANNEL_STATES.closed; + this.bindings = {}; } - /** - * Match only rows where `column` is less than or equal to `value`. - * - * @param column - The column to filter on - * @param value - The value to filter with - */ - lte(column, value) { - this.url.searchParams.append(column, `lte.${value}`); - return this; + /** @internal */ + async _fetchWithTimeout(url, options, timeout) { + const controller = new AbortController(); + const id = setTimeout(() => controller.abort(), timeout); + const response = await this.socket.fetch(url, Object.assign(Object.assign({}, options), { signal: controller.signal })); + clearTimeout(id); + return response; } - /** - * Match only rows where `column` matches `pattern` case-sensitively. - * - * @param column - The column to filter on - * @param pattern - The pattern to match with - */ - like(column, pattern) { - this.url.searchParams.append(column, `like.${pattern}`); - return this; + /** @internal */ + _push(event, payload, timeout = this.timeout) { + if (!this.joinedOnce) { + throw `tried to push '${event}' to '${this.topic}' before joining. Use channel.subscribe() before pushing events`; + } + let pushEvent = new push_1.default(this, event, payload, timeout); + if (this._canPush()) { + pushEvent.send(); + } + else { + this._addToPushBuffer(pushEvent); + } + return pushEvent; } - /** - * Match only rows where `column` matches all of `patterns` case-sensitively. - * - * @param column - The column to filter on - * @param patterns - The patterns to match with - */ - likeAllOf(column, patterns) { - this.url.searchParams.append(column, `like(all).{${patterns.join(',')}}`); - return this; + /** @internal */ + _addToPushBuffer(pushEvent) { + pushEvent.startTimeout(); + this.pushBuffer.push(pushEvent); + // Enforce buffer size limit + if (this.pushBuffer.length > constants_1.MAX_PUSH_BUFFER_SIZE) { + const removedPush = this.pushBuffer.shift(); + if (removedPush) { + removedPush.destroy(); + this.socket.log('channel', `discarded push due to buffer overflow: ${removedPush.event}`, removedPush.payload); + } + } } /** - * Match only rows where `column` matches any of `patterns` case-sensitively. + * Overridable message hook * - * @param column - The column to filter on - * @param patterns - The patterns to match with - */ - likeAnyOf(column, patterns) { - this.url.searchParams.append(column, `like(any).{${patterns.join(',')}}`); - return this; - } - /** - * Match only rows where `column` matches `pattern` case-insensitively. + * Receives all events for specialized message handling before dispatching to the channel callbacks. + * Must return the payload, modified or unmodified. * - * @param column - The column to filter on - * @param pattern - The pattern to match with + * @internal */ - ilike(column, pattern) { - this.url.searchParams.append(column, `ilike.${pattern}`); + _onMessage(_event, payload, _ref) { + return payload; + } + /** @internal */ + _isMember(topic) { + return this.topic === topic; + } + /** @internal */ + _joinRef() { + return this.joinPush.ref; + } + /** @internal */ + _trigger(type, payload, ref) { + var _a, _b; + const typeLower = type.toLocaleLowerCase(); + const { close, error, leave, join } = constants_1.CHANNEL_EVENTS; + const events = [close, error, leave, join]; + if (ref && events.indexOf(typeLower) >= 0 && ref !== this._joinRef()) { + return; + } + let handledPayload = this._onMessage(typeLower, payload, ref); + if (payload && !handledPayload) { + throw 'channel onMessage callbacks must return the payload, modified or unmodified'; + } + if (['insert', 'update', 'delete'].includes(typeLower)) { + (_a = this.bindings.postgres_changes) === null || _a === void 0 ? void 0 : _a.filter((bind) => { + var _a, _b, _c; + return ((_a = bind.filter) === null || _a === void 0 ? void 0 : _a.event) === '*' || ((_c = (_b = bind.filter) === null || _b === void 0 ? void 0 : _b.event) === null || _c === void 0 ? void 0 : _c.toLocaleLowerCase()) === typeLower; + }).map((bind) => bind.callback(handledPayload, ref)); + } + else { + (_b = this.bindings[typeLower]) === null || _b === void 0 ? void 0 : _b.filter((bind) => { + var _a, _b, _c, _d, _e, _f; + if (['broadcast', 'presence', 'postgres_changes'].includes(typeLower)) { + if ('id' in bind) { + const bindId = bind.id; + const bindEvent = (_a = bind.filter) === null || _a === void 0 ? void 0 : _a.event; + return (bindId && + ((_b = payload.ids) === null || _b === void 0 ? void 0 : _b.includes(bindId)) && + (bindEvent === '*' || + (bindEvent === null || bindEvent === void 0 ? void 0 : bindEvent.toLocaleLowerCase()) === ((_c = payload.data) === null || _c === void 0 ? void 0 : _c.type.toLocaleLowerCase()))); + } + else { + const bindEvent = (_e = (_d = bind === null || bind === void 0 ? void 0 : bind.filter) === null || _d === void 0 ? void 0 : _d.event) === null || _e === void 0 ? void 0 : _e.toLocaleLowerCase(); + return bindEvent === '*' || bindEvent === ((_f = payload === null || payload === void 0 ? void 0 : payload.event) === null || _f === void 0 ? void 0 : _f.toLocaleLowerCase()); + } + } + else { + return bind.type.toLocaleLowerCase() === typeLower; + } + }).map((bind) => { + if (typeof handledPayload === 'object' && 'ids' in handledPayload) { + const postgresChanges = handledPayload.data; + const { schema, table, commit_timestamp, type, errors } = postgresChanges; + const enrichedPayload = { + schema: schema, + table: table, + commit_timestamp: commit_timestamp, + eventType: type, + new: {}, + old: {}, + errors: errors, + }; + handledPayload = Object.assign(Object.assign({}, enrichedPayload), this._getPayloadRecords(postgresChanges)); + } + bind.callback(handledPayload, ref); + }); + } + } + /** @internal */ + _isClosed() { + return this.state === constants_1.CHANNEL_STATES.closed; + } + /** @internal */ + _isJoined() { + return this.state === constants_1.CHANNEL_STATES.joined; + } + /** @internal */ + _isJoining() { + return this.state === constants_1.CHANNEL_STATES.joining; + } + /** @internal */ + _isLeaving() { + return this.state === constants_1.CHANNEL_STATES.leaving; + } + /** @internal */ + _replyEventName(ref) { + return `chan_reply_${ref}`; + } + /** @internal */ + _on(type, filter, callback) { + const typeLower = type.toLocaleLowerCase(); + const binding = { + type: typeLower, + filter: filter, + callback: callback, + }; + if (this.bindings[typeLower]) { + this.bindings[typeLower].push(binding); + } + else { + this.bindings[typeLower] = [binding]; + } return this; } - /** - * Match only rows where `column` matches all of `patterns` case-insensitively. - * - * @param column - The column to filter on - * @param patterns - The patterns to match with - */ - ilikeAllOf(column, patterns) { - this.url.searchParams.append(column, `ilike(all).{${patterns.join(',')}}`); + /** @internal */ + _off(type, filter) { + const typeLower = type.toLocaleLowerCase(); + if (this.bindings[typeLower]) { + this.bindings[typeLower] = this.bindings[typeLower].filter((bind) => { + var _a; + return !(((_a = bind.type) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase()) === typeLower && + RealtimeChannel.isEqual(bind.filter, filter)); + }); + } return this; } + /** @internal */ + static isEqual(obj1, obj2) { + if (Object.keys(obj1).length !== Object.keys(obj2).length) { + return false; + } + for (const k in obj1) { + if (obj1[k] !== obj2[k]) { + return false; + } + } + return true; + } /** - * Match only rows where `column` matches any of `patterns` case-insensitively. - * - * @param column - The column to filter on - * @param patterns - The patterns to match with + * Compares two optional filter values for equality. + * Treats undefined, null, and empty string as equivalent empty values. + * @internal */ - ilikeAnyOf(column, patterns) { - this.url.searchParams.append(column, `ilike(any).{${patterns.join(',')}}`); - return this; + static isFilterValueEqual(serverValue, clientValue) { + const normalizedServer = serverValue !== null && serverValue !== void 0 ? serverValue : undefined; + const normalizedClient = clientValue !== null && clientValue !== void 0 ? clientValue : undefined; + return normalizedServer === normalizedClient; + } + /** @internal */ + _rejoinUntilConnected() { + this.rejoinTimer.scheduleTimeout(); + if (this.socket.isConnected()) { + this._rejoin(); + } } /** - * Match only rows where `column` IS `value`. - * - * For non-boolean columns, this is only relevant for checking if the value of - * `column` is NULL by setting `value` to `null`. - * - * For boolean columns, you can also set `value` to `true` or `false` and it - * will behave the same way as `.eq()`. + * Registers a callback that will be executed when the channel closes. * - * @param column - The column to filter on - * @param value - The value to filter with + * @internal */ - is(column, value) { - this.url.searchParams.append(column, `is.${value}`); - return this; + _onClose(callback) { + this._on(constants_1.CHANNEL_EVENTS.close, {}, callback); } /** - * Match only rows where `column` is included in the `values` array. + * Registers a callback that will be executed when the channel encounteres an error. * - * @param column - The column to filter on - * @param values - The values array to filter with + * @internal */ - in(column, values) { - const cleanedValues = values - .map((s) => { - // handle postgrest reserved characters - // https://postgrest.org/en/v7.0.0/api.html#reserved-characters - if (typeof s === 'string' && new RegExp('[,()]').test(s)) - return `"${s}"`; - else - return `${s}`; - }) - .join(','); - this.url.searchParams.append(column, `in.(${cleanedValues})`); - return this; + _onError(callback) { + this._on(constants_1.CHANNEL_EVENTS.error, {}, (reason) => callback(reason)); } /** - * Only relevant for jsonb, array, and range columns. Match only rows where - * `column` contains every element appearing in `value`. + * Returns `true` if the socket is connected and the channel has been joined. * - * @param column - The jsonb, array, or range column to filter on - * @param value - The jsonb, array, or range value to filter with + * @internal */ - contains(column, value) { - if (typeof value === 'string') { - // range types can be inclusive '[', ']' or exclusive '(', ')' so just - // keep it simple and accept a string - this.url.searchParams.append(column, `cs.${value}`); + _canPush() { + return this.socket.isConnected() && this._isJoined(); + } + /** @internal */ + _rejoin(timeout = this.timeout) { + if (this._isLeaving()) { + return; } - else if (Array.isArray(value)) { - // array - this.url.searchParams.append(column, `cs.{${value.join(',')}}`); + this.socket._leaveOpenTopic(this.topic); + this.state = constants_1.CHANNEL_STATES.joining; + this.joinPush.resend(timeout); + } + /** @internal */ + _getPayloadRecords(payload) { + const records = { + new: {}, + old: {}, + }; + if (payload.type === 'INSERT' || payload.type === 'UPDATE') { + records.new = Transformers.convertChangeData(payload.columns, payload.record); } - else { - // json - this.url.searchParams.append(column, `cs.${JSON.stringify(value)}`); + if (payload.type === 'UPDATE' || payload.type === 'DELETE') { + records.old = Transformers.convertChangeData(payload.columns, payload.old_record); } - return this; + return records; } +} +exports["default"] = RealtimeChannel; +//# sourceMappingURL=RealtimeChannel.js.map + +/***/ }), + +/***/ 9103: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +const tslib_1 = __nccwpck_require__(7647); +const websocket_factory_1 = tslib_1.__importDefault(__nccwpck_require__(3478)); +const constants_1 = __nccwpck_require__(88); +const serializer_1 = tslib_1.__importDefault(__nccwpck_require__(5360)); +const timer_1 = tslib_1.__importDefault(__nccwpck_require__(2983)); +const transformers_1 = __nccwpck_require__(1140); +const RealtimeChannel_1 = tslib_1.__importDefault(__nccwpck_require__(9911)); +const noop = () => { }; +// Connection-related constants +const CONNECTION_TIMEOUTS = { + HEARTBEAT_INTERVAL: 25000, + RECONNECT_DELAY: 10, + HEARTBEAT_TIMEOUT_FALLBACK: 100, +}; +const RECONNECT_INTERVALS = [1000, 2000, 5000, 10000]; +const DEFAULT_RECONNECT_FALLBACK = 10000; +const WORKER_SCRIPT = ` + addEventListener("message", (e) => { + if (e.data.event === "start") { + setInterval(() => postMessage({ event: "keepAlive" }), e.data.interval); + } + });`; +class RealtimeClient { /** - * Only relevant for jsonb, array, and range columns. Match only rows where - * every element appearing in `column` is contained by `value`. + * Initializes the Socket. + * + * @param endPoint The string WebSocket endpoint, ie, "ws://example.com/socket", "wss://example.com", "/socket" (inherited host & protocol) + * @param httpEndpoint The string HTTP endpoint, ie, "https://example.com", "/" (inherited host & protocol) + * @param options.transport The Websocket Transport, for example WebSocket. This can be a custom implementation + * @param options.timeout The default timeout in milliseconds to trigger push timeouts. + * @param options.params The optional params to pass when connecting. + * @param options.headers Deprecated: headers cannot be set on websocket connections and this option will be removed in the future. + * @param options.heartbeatIntervalMs The millisec interval to send a heartbeat message. + * @param options.heartbeatCallback The optional function to handle heartbeat status and latency. + * @param options.logger The optional function for specialized logging, ie: logger: (kind, msg, data) => { console.log(`${kind}: ${msg}`, data) } + * @param options.logLevel Sets the log level for Realtime + * @param options.encode The function to encode outgoing messages. Defaults to JSON: (payload, callback) => callback(JSON.stringify(payload)) + * @param options.decode The function to decode incoming messages. Defaults to Serializer's decode. + * @param options.reconnectAfterMs he optional function that returns the millsec reconnect interval. Defaults to stepped backoff off. + * @param options.worker Use Web Worker to set a side flow. Defaults to false. + * @param options.workerUrl The URL of the worker script. Defaults to https://realtime.supabase.com/worker.js that includes a heartbeat event call to keep the connection alive. + * @param options.vsn The protocol version to use when connecting. Supported versions are "1.0.0" and "2.0.0". Defaults to "2.0.0". + * @example + * ```ts + * import RealtimeClient from '@supabase/realtime-js' * - * @param column - The jsonb, array, or range column to filter on - * @param value - The jsonb, array, or range value to filter with + * const client = new RealtimeClient('https://xyzcompany.supabase.co/realtime/v1', { + * params: { apikey: 'public-anon-key' }, + * }) + * client.connect() + * ``` + */ + constructor(endPoint, options) { + var _a; + this.accessTokenValue = null; + this.apiKey = null; + this._manuallySetToken = false; + this.channels = new Array(); + this.endPoint = ''; + this.httpEndpoint = ''; + /** @deprecated headers cannot be set on websocket connections */ + this.headers = {}; + this.params = {}; + this.timeout = constants_1.DEFAULT_TIMEOUT; + this.transport = null; + this.heartbeatIntervalMs = CONNECTION_TIMEOUTS.HEARTBEAT_INTERVAL; + this.heartbeatTimer = undefined; + this.pendingHeartbeatRef = null; + this.heartbeatCallback = noop; + this.ref = 0; + this.reconnectTimer = null; + this.vsn = constants_1.DEFAULT_VSN; + this.logger = noop; + this.conn = null; + this.sendBuffer = []; + this.serializer = new serializer_1.default(); + this.stateChangeCallbacks = { + open: [], + close: [], + error: [], + message: [], + }; + this.accessToken = null; + this._connectionState = 'disconnected'; + this._wasManualDisconnect = false; + this._authPromise = null; + this._heartbeatSentAt = null; + /** + * Use either custom fetch, if provided, or default fetch to make HTTP requests + * + * @internal + */ + this._resolveFetch = (customFetch) => { + if (customFetch) { + return (...args) => customFetch(...args); + } + return (...args) => fetch(...args); + }; + // Validate required parameters + if (!((_a = options === null || options === void 0 ? void 0 : options.params) === null || _a === void 0 ? void 0 : _a.apikey)) { + throw new Error('API key is required to connect to Realtime'); + } + this.apiKey = options.params.apikey; + // Initialize endpoint URLs + this.endPoint = `${endPoint}/${constants_1.TRANSPORTS.websocket}`; + this.httpEndpoint = (0, transformers_1.httpEndpointURL)(endPoint); + this._initializeOptions(options); + this._setupReconnectionTimer(); + this.fetch = this._resolveFetch(options === null || options === void 0 ? void 0 : options.fetch); + } + /** + * Connects the socket, unless already connected. */ - containedBy(column, value) { - if (typeof value === 'string') { - // range - this.url.searchParams.append(column, `cd.${value}`); + connect() { + // Skip if already connecting, disconnecting, or connected + if (this.isConnecting() || + this.isDisconnecting() || + (this.conn !== null && this.isConnected())) { + return; + } + this._setConnectionState('connecting'); + // Trigger auth if needed and not already in progress + // This ensures auth is called for standalone RealtimeClient usage + // while avoiding race conditions with SupabaseClient's immediate setAuth call + if (this.accessToken && !this._authPromise) { + this._setAuthSafely('connect'); } - else if (Array.isArray(value)) { - // array - this.url.searchParams.append(column, `cd.{${value.join(',')}}`); + // Establish WebSocket connection + if (this.transport) { + // Use custom transport if provided + this.conn = new this.transport(this.endpointURL()); } else { - // json - this.url.searchParams.append(column, `cd.${JSON.stringify(value)}`); + // Try to use native WebSocket + try { + this.conn = websocket_factory_1.default.createWebSocket(this.endpointURL()); + } + catch (error) { + this._setConnectionState('disconnected'); + const errorMessage = error.message; + // Provide helpful error message based on environment + if (errorMessage.includes('Node.js')) { + throw new Error(`${errorMessage}\n\n` + + 'To use Realtime in Node.js, you need to provide a WebSocket implementation:\n\n' + + 'Option 1: Use Node.js 22+ which has native WebSocket support\n' + + 'Option 2: Install and provide the "ws" package:\n\n' + + ' npm install ws\n\n' + + ' import ws from "ws"\n' + + ' const client = new RealtimeClient(url, {\n' + + ' ...options,\n' + + ' transport: ws\n' + + ' })'); + } + throw new Error(`WebSocket not available: ${errorMessage}`); + } } - return this; + this._setupConnectionHandlers(); } /** - * Only relevant for range columns. Match only rows where every element in - * `column` is greater than any element in `range`. - * - * @param column - The range column to filter on - * @param range - The range to filter with + * Returns the URL of the websocket. + * @returns string The URL of the websocket. */ - rangeGt(column, range) { - this.url.searchParams.append(column, `sr.${range}`); - return this; + endpointURL() { + return this._appendParams(this.endPoint, Object.assign({}, this.params, { vsn: this.vsn })); } /** - * Only relevant for range columns. Match only rows where every element in - * `column` is either contained in `range` or greater than any element in - * `range`. + * Disconnects the socket. * - * @param column - The range column to filter on - * @param range - The range to filter with + * @param code A numeric status code to send on disconnect. + * @param reason A custom reason for the disconnect. */ - rangeGte(column, range) { - this.url.searchParams.append(column, `nxl.${range}`); - return this; + disconnect(code, reason) { + if (this.isDisconnecting()) { + return; + } + this._setConnectionState('disconnecting', true); + if (this.conn) { + // Setup fallback timer to prevent hanging in disconnecting state + const fallbackTimer = setTimeout(() => { + this._setConnectionState('disconnected'); + }, 100); + this.conn.onclose = () => { + clearTimeout(fallbackTimer); + this._setConnectionState('disconnected'); + }; + // Close the WebSocket connection if close method exists + if (typeof this.conn.close === 'function') { + if (code) { + this.conn.close(code, reason !== null && reason !== void 0 ? reason : ''); + } + else { + this.conn.close(); + } + } + this._teardownConnection(); + } + else { + this._setConnectionState('disconnected'); + } } /** - * Only relevant for range columns. Match only rows where every element in - * `column` is less than any element in `range`. - * - * @param column - The range column to filter on - * @param range - The range to filter with + * Returns all created channels */ - rangeLt(column, range) { - this.url.searchParams.append(column, `sl.${range}`); - return this; + getChannels() { + return this.channels; } /** - * Only relevant for range columns. Match only rows where every element in - * `column` is either contained in `range` or less than any element in - * `range`. - * - * @param column - The range column to filter on - * @param range - The range to filter with + * Unsubscribes and removes a single channel + * @param channel A RealtimeChannel instance */ - rangeLte(column, range) { - this.url.searchParams.append(column, `nxr.${range}`); - return this; + async removeChannel(channel) { + const status = await channel.unsubscribe(); + if (this.channels.length === 0) { + this.disconnect(); + } + return status; } /** - * Only relevant for range columns. Match only rows where `column` is - * mutually exclusive to `range` and there can be no element between the two - * ranges. - * - * @param column - The range column to filter on - * @param range - The range to filter with + * Unsubscribes and removes all channels */ - rangeAdjacent(column, range) { - this.url.searchParams.append(column, `adj.${range}`); - return this; + async removeAllChannels() { + const values_1 = await Promise.all(this.channels.map((channel) => channel.unsubscribe())); + this.channels = []; + this.disconnect(); + return values_1; } /** - * Only relevant for array and range columns. Match only rows where - * `column` and `value` have an element in common. + * Logs the message. * - * @param column - The array or range column to filter on - * @param value - The array or range value to filter with + * For customized logging, `this.logger` can be overridden. */ - overlaps(column, value) { - if (typeof value === 'string') { - // range - this.url.searchParams.append(column, `ov.${value}`); - } - else { - // array - this.url.searchParams.append(column, `ov.{${value.join(',')}}`); - } - return this; + log(kind, msg, data) { + this.logger(kind, msg, data); } /** - * Only relevant for text and tsvector columns. Match only rows where - * `column` matches the query string in `query`. - * - * @param column - The text or tsvector column to filter on - * @param query - The query text to match with - * @param options - Named parameters - * @param options.config - The text search configuration to use - * @param options.type - Change how the `query` text is interpreted + * Returns the current state of the socket. */ - textSearch(column, query, { config, type } = {}) { - let typePart = ''; - if (type === 'plain') { - typePart = 'pl'; - } - else if (type === 'phrase') { - typePart = 'ph'; - } - else if (type === 'websearch') { - typePart = 'w'; + connectionState() { + switch (this.conn && this.conn.readyState) { + case constants_1.SOCKET_STATES.connecting: + return constants_1.CONNECTION_STATE.Connecting; + case constants_1.SOCKET_STATES.open: + return constants_1.CONNECTION_STATE.Open; + case constants_1.SOCKET_STATES.closing: + return constants_1.CONNECTION_STATE.Closing; + default: + return constants_1.CONNECTION_STATE.Closed; } - const configPart = config === undefined ? '' : `(${config})`; - this.url.searchParams.append(column, `${typePart}fts${configPart}.${query}`); - return this; } /** - * Match only rows where each column in `query` keys is equal to its - * associated value. Shorthand for multiple `.eq()`s. - * - * @param query - The object to filter with, with column names as keys mapped - * to their filter values + * Returns `true` is the connection is open. */ - match(query) { - Object.entries(query).forEach(([column, value]) => { - this.url.searchParams.append(column, `eq.${value}`); - }); - return this; + isConnected() { + return this.connectionState() === constants_1.CONNECTION_STATE.Open; } /** - * Match only rows which doesn't satisfy the filter. - * - * Unlike most filters, `opearator` and `value` are used as-is and need to - * follow [PostgREST - * syntax](https://postgrest.org/en/stable/api.html#operators). You also need - * to make sure they are properly sanitized. - * - * @param column - The column to filter on - * @param operator - The operator to be negated to filter with, following - * PostgREST syntax - * @param value - The value to filter with, following PostgREST syntax + * Returns `true` if the connection is currently connecting. */ - not(column, operator, value) { - this.url.searchParams.append(column, `not.${operator}.${value}`); - return this; + isConnecting() { + return this._connectionState === 'connecting'; } /** - * Match only rows which satisfy at least one of the filters. - * - * Unlike most filters, `filters` is used as-is and needs to follow [PostgREST - * syntax](https://postgrest.org/en/stable/api.html#operators). You also need - * to make sure it's properly sanitized. - * - * It's currently not possible to do an `.or()` filter across multiple tables. - * - * @param filters - The filters to use, following PostgREST syntax - * @param foreignTable - Set this to filter on foreign tables instead of the - * current table + * Returns `true` if the connection is currently disconnecting. */ - or(filters, { foreignTable } = {}) { - const key = foreignTable ? `${foreignTable}.or` : 'or'; - this.url.searchParams.append(key, `(${filters})`); - return this; + isDisconnecting() { + return this._connectionState === 'disconnecting'; } /** - * Match only rows which satisfy the filter. This is an escape hatch - you - * should use the specific filter methods wherever possible. - * - * Unlike most filters, `opearator` and `value` are used as-is and need to - * follow [PostgREST - * syntax](https://postgrest.org/en/stable/api.html#operators). You also need - * to make sure they are properly sanitized. + * Creates (or reuses) a {@link RealtimeChannel} for the provided topic. * - * @param column - The column to filter on - * @param operator - The operator to filter with, following PostgREST syntax - * @param value - The value to filter with, following PostgREST syntax + * Topics are automatically prefixed with `realtime:` to match the Realtime service. + * If a channel with the same topic already exists it will be returned instead of creating + * a duplicate connection. */ - filter(column, operator, value) { - this.url.searchParams.append(column, `${operator}.${value}`); - return this; - } -} -exports["default"] = PostgrestFilterBuilder; -//# sourceMappingURL=PostgrestFilterBuilder.js.map - -/***/ }), - -/***/ 5683: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -const PostgrestFilterBuilder_1 = __importDefault(__nccwpck_require__(1446)); -class PostgrestQueryBuilder { - constructor(url, { headers = {}, schema, fetch, }) { - this.url = url; - this.headers = headers; - this.schema = schema; - this.fetch = fetch; + channel(topic, params = { config: {} }) { + const realtimeTopic = `realtime:${topic}`; + const exists = this.getChannels().find((c) => c.topic === realtimeTopic); + if (!exists) { + const chan = new RealtimeChannel_1.default(`realtime:${topic}`, params, this); + this.channels.push(chan); + return chan; + } + else { + return exists; + } } /** - * Perform a SELECT query on the table or view. - * - * @param columns - The columns to retrieve, separated by commas. Columns can be renamed when returned with `customName:columnName` - * - * @param options - Named parameters - * - * @param options.head - When set to `true`, `data` will not be returned. - * Useful if you only need the count. - * - * @param options.count - Count algorithm to use to count rows in the table or view. - * - * `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the - * hood. - * - * `"planned"`: Approximated but fast count algorithm. Uses the Postgres - * statistics under the hood. + * Push out a message if the socket is connected. * - * `"estimated"`: Uses exact count for low numbers and planned count for high - * numbers. + * If the socket is not connected, the message gets enqueued within a local buffer, and sent out when a connection is next established. */ - select(columns, { head = false, count, } = {}) { - const method = head ? 'HEAD' : 'GET'; - // Remove whitespaces except when quoted - let quoted = false; - const cleanedColumns = (columns !== null && columns !== void 0 ? columns : '*') - .split('') - .map((c) => { - if (/\s/.test(c) && !quoted) { - return ''; - } - if (c === '"') { - quoted = !quoted; - } - return c; - }) - .join(''); - this.url.searchParams.set('select', cleanedColumns); - if (count) { - this.headers['Prefer'] = `count=${count}`; + push(data) { + const { topic, event, payload, ref } = data; + const callback = () => { + this.encode(data, (result) => { + var _a; + (_a = this.conn) === null || _a === void 0 ? void 0 : _a.send(result); + }); + }; + this.log('push', `${topic} ${event} (${ref})`, payload); + if (this.isConnected()) { + callback(); + } + else { + this.sendBuffer.push(callback); } - return new PostgrestFilterBuilder_1.default({ - method, - url: this.url, - headers: this.headers, - schema: this.schema, - fetch: this.fetch, - allowEmpty: false, - }); } /** - * Perform an INSERT into the table or view. - * - * By default, inserted rows are not returned. To return it, chain the call - * with `.select()`. - * - * @param values - The values to insert. Pass an object to insert a single row - * or an array to insert multiple rows. + * Sets the JWT access token used for channel subscription authorization and Realtime RLS. * - * @param options - Named parameters + * If param is null it will use the `accessToken` callback function or the token set on the client. * - * @param options.count - Count algorithm to use to count inserted rows. + * On callback used, it will set the value of the token internal to the client. * - * `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the - * hood. + * When a token is explicitly provided, it will be preserved across channel operations + * (including removeChannel and resubscribe). The `accessToken` callback will not be + * invoked until `setAuth()` is called without arguments. * - * `"planned"`: Approximated but fast count algorithm. Uses the Postgres - * statistics under the hood. + * @param token A JWT string to override the token set on the client. * - * `"estimated"`: Uses exact count for low numbers and planned count for high - * numbers. + * @example + * // Use a manual token (preserved across resubscribes, ignores accessToken callback) + * client.realtime.setAuth('my-custom-jwt') * - * @param options.defaultToNull - Make missing fields default to `null`. - * Otherwise, use the default value for the column. Only applies for bulk - * inserts. + * // Switch back to using the accessToken callback + * client.realtime.setAuth() */ - insert(values, { count, defaultToNull = true, } = {}) { - const method = 'POST'; - const prefersHeaders = []; - if (this.headers['Prefer']) { - prefersHeaders.push(this.headers['Prefer']); - } - if (count) { - prefersHeaders.push(`count=${count}`); - } - if (!defaultToNull) { - prefersHeaders.push('missing=default'); + async setAuth(token = null) { + this._authPromise = this._performAuth(token); + try { + await this._authPromise; } - this.headers['Prefer'] = prefersHeaders.join(','); - if (Array.isArray(values)) { - const columns = values.reduce((acc, x) => acc.concat(Object.keys(x)), []); - if (columns.length > 0) { - const uniqueColumns = [...new Set(columns)].map((column) => `"${column}"`); - this.url.searchParams.set('columns', uniqueColumns.join(',')); - } + finally { + this._authPromise = null; } - return new PostgrestFilterBuilder_1.default({ - method, - url: this.url, - headers: this.headers, - schema: this.schema, - body: values, - fetch: this.fetch, - allowEmpty: false, - }); } /** - * Perform an UPSERT on the table or view. Depending on the column(s) passed - * to `onConflict`, `.upsert()` allows you to perform the equivalent of - * `.insert()` if a row with the corresponding `onConflict` columns doesn't - * exist, or if it does exist, perform an alternative action depending on - * `ignoreDuplicates`. - * - * By default, upserted rows are not returned. To return it, chain the call - * with `.select()`. - * - * @param values - The values to upsert with. Pass an object to upsert a - * single row or an array to upsert multiple rows. - * - * @param options - Named parameters - * - * @param options.onConflict - Comma-separated UNIQUE column(s) to specify how - * duplicate rows are determined. Two rows are duplicates if all the - * `onConflict` columns are equal. - * - * @param options.ignoreDuplicates - If `true`, duplicate rows are ignored. If - * `false`, duplicate rows are merged with existing rows. - * - * @param options.count - Count algorithm to use to count upserted rows. - * - * `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the - * hood. - * - * `"planned"`: Approximated but fast count algorithm. Uses the Postgres - * statistics under the hood. - * - * `"estimated"`: Uses exact count for low numbers and planned count for high - * numbers. - * - * @param options.defaultToNull - Make missing fields default to `null`. - * Otherwise, use the default value for the column. This only applies when - * inserting new rows, not when merging with existing rows under - * `ignoreDuplicates: false`. This also only applies when doing bulk upserts. + * Returns true if the current access token was explicitly set via setAuth(token), + * false if it was obtained via the accessToken callback. + * @internal */ - upsert(values, { onConflict, ignoreDuplicates = false, count, defaultToNull = true, } = {}) { - const method = 'POST'; - const prefersHeaders = [`resolution=${ignoreDuplicates ? 'ignore' : 'merge'}-duplicates`]; - if (onConflict !== undefined) - this.url.searchParams.set('on_conflict', onConflict); - if (this.headers['Prefer']) { - prefersHeaders.push(this.headers['Prefer']); - } - if (count) { - prefersHeaders.push(`count=${count}`); - } - if (!defaultToNull) { - prefersHeaders.push('missing=default'); - } - this.headers['Prefer'] = prefersHeaders.join(','); - if (Array.isArray(values)) { - const columns = values.reduce((acc, x) => acc.concat(Object.keys(x)), []); - if (columns.length > 0) { - const uniqueColumns = [...new Set(columns)].map((column) => `"${column}"`); - this.url.searchParams.set('columns', uniqueColumns.join(',')); - } - } - return new PostgrestFilterBuilder_1.default({ - method, - url: this.url, - headers: this.headers, - schema: this.schema, - body: values, - fetch: this.fetch, - allowEmpty: false, - }); + _isManualToken() { + return this._manuallySetToken; } /** - * Perform an UPDATE on the table or view. - * - * By default, updated rows are not returned. To return it, chain the call - * with `.select()` after filters. - * - * @param values - The values to update with - * - * @param options - Named parameters - * - * @param options.count - Count algorithm to use to count updated rows. - * - * `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the - * hood. - * - * `"planned"`: Approximated but fast count algorithm. Uses the Postgres - * statistics under the hood. - * - * `"estimated"`: Uses exact count for low numbers and planned count for high - * numbers. + * Sends a heartbeat message if the socket is connected. */ - update(values, { count, } = {}) { - const method = 'PATCH'; - const prefersHeaders = []; - if (this.headers['Prefer']) { - prefersHeaders.push(this.headers['Prefer']); - } - if (count) { - prefersHeaders.push(`count=${count}`); - } - this.headers['Prefer'] = prefersHeaders.join(','); - return new PostgrestFilterBuilder_1.default({ - method, - url: this.url, - headers: this.headers, - schema: this.schema, - body: values, - fetch: this.fetch, - allowEmpty: false, + async sendHeartbeat() { + var _a; + if (!this.isConnected()) { + try { + this.heartbeatCallback('disconnected'); + } + catch (e) { + this.log('error', 'error in heartbeat callback', e); + } + return; + } + // Handle heartbeat timeout and force reconnection if needed + if (this.pendingHeartbeatRef) { + this.pendingHeartbeatRef = null; + this._heartbeatSentAt = null; + this.log('transport', 'heartbeat timeout. Attempting to re-establish connection'); + try { + this.heartbeatCallback('timeout'); + } + catch (e) { + this.log('error', 'error in heartbeat callback', e); + } + // Force reconnection after heartbeat timeout + this._wasManualDisconnect = false; + (_a = this.conn) === null || _a === void 0 ? void 0 : _a.close(constants_1.WS_CLOSE_NORMAL, 'heartbeat timeout'); + setTimeout(() => { + var _a; + if (!this.isConnected()) { + (_a = this.reconnectTimer) === null || _a === void 0 ? void 0 : _a.scheduleTimeout(); + } + }, CONNECTION_TIMEOUTS.HEARTBEAT_TIMEOUT_FALLBACK); + return; + } + // Send heartbeat message to server + this._heartbeatSentAt = Date.now(); + this.pendingHeartbeatRef = this._makeRef(); + this.push({ + topic: 'phoenix', + event: 'heartbeat', + payload: {}, + ref: this.pendingHeartbeatRef, }); + try { + this.heartbeatCallback('sent'); + } + catch (e) { + this.log('error', 'error in heartbeat callback', e); + } + this._setAuthSafely('heartbeat'); } /** - * Perform a DELETE on the table or view. - * - * By default, deleted rows are not returned. To return it, chain the call - * with `.select()` after filters. - * - * @param options - Named parameters + * Sets a callback that receives lifecycle events for internal heartbeat messages. + * Useful for instrumenting connection health (e.g. sent/ok/timeout/disconnected). + */ + onHeartbeat(callback) { + this.heartbeatCallback = callback; + } + /** + * Flushes send buffer + */ + flushSendBuffer() { + if (this.isConnected() && this.sendBuffer.length > 0) { + this.sendBuffer.forEach((callback) => callback()); + this.sendBuffer = []; + } + } + /** + * Return the next message ref, accounting for overflows * - * @param options.count - Count algorithm to use to count deleted rows. + * @internal + */ + _makeRef() { + let newRef = this.ref + 1; + if (newRef === this.ref) { + this.ref = 0; + } + else { + this.ref = newRef; + } + return this.ref.toString(); + } + /** + * Unsubscribe from channels with the specified topic. * - * `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the - * hood. + * @internal + */ + _leaveOpenTopic(topic) { + let dupChannel = this.channels.find((c) => c.topic === topic && (c._isJoined() || c._isJoining())); + if (dupChannel) { + this.log('transport', `leaving duplicate topic "${topic}"`); + dupChannel.unsubscribe(); + } + } + /** + * Removes a subscription from the socket. * - * `"planned"`: Approximated but fast count algorithm. Uses the Postgres - * statistics under the hood. + * @param channel An open subscription. * - * `"estimated"`: Uses exact count for low numbers and planned count for high - * numbers. + * @internal */ - delete({ count, } = {}) { - const method = 'DELETE'; - const prefersHeaders = []; - if (count) { - prefersHeaders.push(`count=${count}`); - } - if (this.headers['Prefer']) { - prefersHeaders.unshift(this.headers['Prefer']); - } - this.headers['Prefer'] = prefersHeaders.join(','); - return new PostgrestFilterBuilder_1.default({ - method, - url: this.url, - headers: this.headers, - schema: this.schema, - fetch: this.fetch, - allowEmpty: false, + _remove(channel) { + this.channels = this.channels.filter((c) => c.topic !== channel.topic); + } + /** @internal */ + _onConnMessage(rawMessage) { + this.decode(rawMessage.data, (msg) => { + // Handle heartbeat responses + if (msg.topic === 'phoenix' && + msg.event === 'phx_reply' && + msg.ref && + msg.ref === this.pendingHeartbeatRef) { + const latency = this._heartbeatSentAt ? Date.now() - this._heartbeatSentAt : undefined; + try { + this.heartbeatCallback(msg.payload.status === 'ok' ? 'ok' : 'error', latency); + } + catch (e) { + this.log('error', 'error in heartbeat callback', e); + } + this._heartbeatSentAt = null; + this.pendingHeartbeatRef = null; + } + // Log incoming message + const { topic, event, payload, ref } = msg; + const refString = ref ? `(${ref})` : ''; + const status = payload.status || ''; + this.log('receive', `${status} ${topic} ${event} ${refString}`.trim(), payload); + // Route message to appropriate channels + this.channels + .filter((channel) => channel._isMember(topic)) + .forEach((channel) => channel._trigger(event, payload, ref)); + this._triggerStateCallbacks('message', msg); }); } -} -exports["default"] = PostgrestQueryBuilder; -//# sourceMappingURL=PostgrestQueryBuilder.js.map - -/***/ }), - -/***/ 39: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -const PostgrestBuilder_1 = __importDefault(__nccwpck_require__(9963)); -class PostgrestTransformBuilder extends PostgrestBuilder_1.default { /** - * Perform a SELECT on the query result. - * - * By default, `.insert()`, `.update()`, `.upsert()`, and `.delete()` do not - * return modified rows. By calling this method, modified rows are returned in - * `data`. - * - * @param columns - The columns to retrieve, separated by commas + * Clear specific timer + * @internal */ - select(columns) { - // Remove whitespaces except when quoted - let quoted = false; - const cleanedColumns = (columns !== null && columns !== void 0 ? columns : '*') - .split('') - .map((c) => { - if (/\s/.test(c) && !quoted) { - return ''; - } - if (c === '"') { - quoted = !quoted; - } - return c; - }) - .join(''); - this.url.searchParams.set('select', cleanedColumns); - if (this.headers['Prefer']) { - this.headers['Prefer'] += ','; + _clearTimer(timer) { + var _a; + if (timer === 'heartbeat' && this.heartbeatTimer) { + clearInterval(this.heartbeatTimer); + this.heartbeatTimer = undefined; + } + else if (timer === 'reconnect') { + (_a = this.reconnectTimer) === null || _a === void 0 ? void 0 : _a.reset(); } - this.headers['Prefer'] += 'return=representation'; - return this; } /** - * Order the query result by `column`. - * - * You can call this method multiple times to order by multiple columns. - * - * You can order foreign tables, but it doesn't affect the ordering of the - * current table. - * - * @param column - The column to order by - * @param options - Named parameters - * @param options.ascending - If `true`, the result will be in ascending order - * @param options.nullsFirst - If `true`, `null`s appear first. If `false`, - * `null`s appear last. - * @param options.foreignTable - Set this to order a foreign table by foreign - * columns + * Clear all timers + * @internal */ - order(column, { ascending = true, nullsFirst, foreignTable, } = {}) { - const key = foreignTable ? `${foreignTable}.order` : 'order'; - const existingOrder = this.url.searchParams.get(key); - this.url.searchParams.set(key, `${existingOrder ? `${existingOrder},` : ''}${column}.${ascending ? 'asc' : 'desc'}${nullsFirst === undefined ? '' : nullsFirst ? '.nullsfirst' : '.nullslast'}`); - return this; + _clearAllTimers() { + this._clearTimer('heartbeat'); + this._clearTimer('reconnect'); } /** - * Limit the query result by `count`. - * - * @param count - The maximum number of rows to return - * @param options - Named parameters - * @param options.foreignTable - Set this to limit rows of foreign tables - * instead of the current table + * Setup connection handlers for WebSocket events + * @internal */ - limit(count, { foreignTable } = {}) { - const key = typeof foreignTable === 'undefined' ? 'limit' : `${foreignTable}.limit`; - this.url.searchParams.set(key, `${count}`); - return this; + _setupConnectionHandlers() { + if (!this.conn) + return; + // Set binary type if supported (browsers and most WebSocket implementations) + if ('binaryType' in this.conn) { + ; + this.conn.binaryType = 'arraybuffer'; + } + this.conn.onopen = () => this._onConnOpen(); + this.conn.onerror = (error) => this._onConnError(error); + this.conn.onmessage = (event) => this._onConnMessage(event); + this.conn.onclose = (event) => this._onConnClose(event); + if (this.conn.readyState === constants_1.SOCKET_STATES.open) { + this._onConnOpen(); + } } /** - * Limit the query result by starting at an offset (`from`) and ending at the offset (`from + to`). - * Only records within this range are returned. - * This respects the query order and if there is no order clause the range could behave unexpectedly. - * The `from` and `to` values are 0-based and inclusive: `range(1, 3)` will include the second, third - * and fourth rows of the query. - * - * @param from - The starting index from which to limit the result - * @param to - The last index to which to limit the result - * @param options - Named parameters - * @param options.foreignTable - Set this to limit rows of foreign tables - * instead of the current table + * Teardown connection and cleanup resources + * @internal */ - range(from, to, { foreignTable } = {}) { - const keyOffset = typeof foreignTable === 'undefined' ? 'offset' : `${foreignTable}.offset`; - const keyLimit = typeof foreignTable === 'undefined' ? 'limit' : `${foreignTable}.limit`; - this.url.searchParams.set(keyOffset, `${from}`); - // Range is inclusive, so add 1 - this.url.searchParams.set(keyLimit, `${to - from + 1}`); - return this; + _teardownConnection() { + if (this.conn) { + if (this.conn.readyState === constants_1.SOCKET_STATES.open || + this.conn.readyState === constants_1.SOCKET_STATES.connecting) { + try { + this.conn.close(); + } + catch (e) { + this.log('error', 'Error closing connection', e); + } + } + this.conn.onopen = null; + this.conn.onerror = null; + this.conn.onmessage = null; + this.conn.onclose = null; + this.conn = null; + } + this._clearAllTimers(); + this._terminateWorker(); + this.channels.forEach((channel) => channel.teardown()); + } + /** @internal */ + _onConnOpen() { + this._setConnectionState('connected'); + this.log('transport', `connected to ${this.endpointURL()}`); + // Wait for any pending auth operations before flushing send buffer + // This ensures channel join messages include the correct access token + const authPromise = this._authPromise || + (this.accessToken && !this.accessTokenValue ? this.setAuth() : Promise.resolve()); + authPromise + .then(() => { + // When subscribe() is called before the accessToken callback has + // resolved (common on React Native / Expo where token storage is + // async), the phx_join payload captured at subscribe()-time will + // have no access_token. By this point auth has settled and + // this.accessTokenValue holds the real JWT. + // + // The stale join messages sitting in sendBuffer captured the old + // (token-less) payload in a closure, so we cannot simply flush + // them. Instead we: + // 1. Patch each channel's joinPush payload with the real token + // 2. Drop the stale buffered messages + // 3. Re-send the join for any channel still in "joining" state + // + // On browsers this is a harmless no-op: accessTokenValue was + // already set synchronously before subscribe() ran, so the join + // payload already had the correct token. + if (this.accessTokenValue) { + this.channels.forEach((channel) => { + channel.updateJoinPayload({ access_token: this.accessTokenValue }); + }); + this.sendBuffer = []; + this.channels.forEach((channel) => { + if (channel._isJoining()) { + channel.joinPush.sent = false; + channel.joinPush.send(); + } + }); + } + this.flushSendBuffer(); + }) + .catch((e) => { + this.log('error', 'error waiting for auth on connect', e); + // Proceed anyway to avoid hanging connections + this.flushSendBuffer(); + }); + this._clearTimer('reconnect'); + if (!this.worker) { + this._startHeartbeat(); + } + else { + if (!this.workerRef) { + this._startWorkerHeartbeat(); + } + } + this._triggerStateCallbacks('open'); + } + /** @internal */ + _startHeartbeat() { + this.heartbeatTimer && clearInterval(this.heartbeatTimer); + this.heartbeatTimer = setInterval(() => this.sendHeartbeat(), this.heartbeatIntervalMs); + } + /** @internal */ + _startWorkerHeartbeat() { + if (this.workerUrl) { + this.log('worker', `starting worker for from ${this.workerUrl}`); + } + else { + this.log('worker', `starting default worker`); + } + const objectUrl = this._workerObjectUrl(this.workerUrl); + this.workerRef = new Worker(objectUrl); + this.workerRef.onerror = (error) => { + this.log('worker', 'worker error', error.message); + this._terminateWorker(); + }; + this.workerRef.onmessage = (event) => { + if (event.data.event === 'keepAlive') { + this.sendHeartbeat(); + } + }; + this.workerRef.postMessage({ + event: 'start', + interval: this.heartbeatIntervalMs, + }); } /** - * Set the AbortSignal for the fetch request. - * - * @param signal - The AbortSignal to use for the fetch request + * Terminate the Web Worker and clear the reference + * @internal */ - abortSignal(signal) { - this.signal = signal; - return this; + _terminateWorker() { + if (this.workerRef) { + this.log('worker', 'terminating worker'); + this.workerRef.terminate(); + this.workerRef = undefined; + } + } + /** @internal */ + _onConnClose(event) { + var _a; + this._setConnectionState('disconnected'); + this.log('transport', 'close', event); + this._triggerChanError(); + this._clearTimer('heartbeat'); + // Only schedule reconnection if it wasn't a manual disconnect + if (!this._wasManualDisconnect) { + (_a = this.reconnectTimer) === null || _a === void 0 ? void 0 : _a.scheduleTimeout(); + } + this._triggerStateCallbacks('close', event); + } + /** @internal */ + _onConnError(error) { + this._setConnectionState('disconnected'); + this.log('transport', `${error}`); + this._triggerChanError(); + this._triggerStateCallbacks('error', error); + try { + this.heartbeatCallback('error'); + } + catch (e) { + this.log('error', 'error in heartbeat callback', e); + } + } + /** @internal */ + _triggerChanError() { + this.channels.forEach((channel) => channel._trigger(constants_1.CHANNEL_EVENTS.error)); + } + /** @internal */ + _appendParams(url, params) { + if (Object.keys(params).length === 0) { + return url; + } + const prefix = url.match(/\?/) ? '&' : '?'; + const query = new URLSearchParams(params); + return `${url}${prefix}${query}`; + } + _workerObjectUrl(url) { + let result_url; + if (url) { + result_url = url; + } + else { + const blob = new Blob([WORKER_SCRIPT], { type: 'application/javascript' }); + result_url = URL.createObjectURL(blob); + } + return result_url; } /** - * Return `data` as a single object instead of an array of objects. - * - * Query result must be one row (e.g. using `.limit(1)`), otherwise this - * returns an error. + * Set connection state with proper state management + * @internal */ - single() { - this.headers['Accept'] = 'application/vnd.pgrst.object+json'; - return this; + _setConnectionState(state, manual = false) { + this._connectionState = state; + if (state === 'connecting') { + this._wasManualDisconnect = false; + } + else if (state === 'disconnecting') { + this._wasManualDisconnect = manual; + } } /** - * Return `data` as a single object instead of an array of objects. - * - * Query result must be zero or one row (e.g. using `.limit(1)`), otherwise - * this returns an error. + * Perform the actual auth operation + * @internal */ - maybeSingle() { - // Temporary partial fix for https://github.com/supabase/postgrest-js/issues/361 - // Issue persists e.g. for `.insert([...]).select().maybeSingle()` - if (this.method === 'GET') { - this.headers['Accept'] = 'application/json'; + async _performAuth(token = null) { + let tokenToSend; + let isManualToken = false; + if (token) { + tokenToSend = token; + // Track if this is a manually-provided token + isManualToken = true; + } + else if (this.accessToken) { + // Call the accessToken callback to get fresh token + try { + tokenToSend = await this.accessToken(); + } + catch (e) { + this.log('error', 'Error fetching access token from callback', e); + // Fall back to cached value if callback fails + tokenToSend = this.accessTokenValue; + } } else { - this.headers['Accept'] = 'application/vnd.pgrst.object+json'; + tokenToSend = this.accessTokenValue; + } + // Track whether this token was manually set or fetched via callback + if (isManualToken) { + this._manuallySetToken = true; + } + else if (this.accessToken) { + // If we used the callback, clear the manual flag + this._manuallySetToken = false; + } + if (this.accessTokenValue != tokenToSend) { + this.accessTokenValue = tokenToSend; + this.channels.forEach((channel) => { + const payload = { + access_token: tokenToSend, + version: constants_1.DEFAULT_VERSION, + }; + tokenToSend && channel.updateJoinPayload(payload); + if (channel.joinedOnce && channel._isJoined()) { + channel._push(constants_1.CHANNEL_EVENTS.access_token, { + access_token: tokenToSend, + }); + } + }); } - this.isMaybeSingle = true; - return this; } /** - * Return `data` as a string in CSV format. + * Wait for any in-flight auth operations to complete + * @internal */ - csv() { - this.headers['Accept'] = 'text/csv'; - return this; + async _waitForAuthIfNeeded() { + if (this._authPromise) { + await this._authPromise; + } } /** - * Return `data` as an object in [GeoJSON](https://geojson.org) format. + * Safely call setAuth with standardized error handling + * @internal */ - geojson() { - this.headers['Accept'] = 'application/geo+json'; - return this; + _setAuthSafely(context = 'general') { + // Only refresh auth if using callback-based tokens + if (!this._isManualToken()) { + this.setAuth().catch((e) => { + this.log('error', `Error setting auth in ${context}`, e); + }); + } } /** - * Return `data` as the EXPLAIN plan for the query. - * - * @param options - Named parameters - * - * @param options.analyze - If `true`, the query will be executed and the - * actual run time will be returned + * Trigger state change callbacks with proper error handling + * @internal + */ + _triggerStateCallbacks(event, data) { + try { + this.stateChangeCallbacks[event].forEach((callback) => { + try { + callback(data); + } + catch (e) { + this.log('error', `error in ${event} callback`, e); + } + }); + } + catch (e) { + this.log('error', `error triggering ${event} callbacks`, e); + } + } + /** + * Setup reconnection timer with proper configuration + * @internal + */ + _setupReconnectionTimer() { + this.reconnectTimer = new timer_1.default(async () => { + setTimeout(async () => { + await this._waitForAuthIfNeeded(); + if (!this.isConnected()) { + this.connect(); + } + }, CONNECTION_TIMEOUTS.RECONNECT_DELAY); + }, this.reconnectAfterMs); + } + /** + * Initialize client options with defaults + * @internal + */ + _initializeOptions(options) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; + // Set defaults + this.transport = (_a = options === null || options === void 0 ? void 0 : options.transport) !== null && _a !== void 0 ? _a : null; + this.timeout = (_b = options === null || options === void 0 ? void 0 : options.timeout) !== null && _b !== void 0 ? _b : constants_1.DEFAULT_TIMEOUT; + this.heartbeatIntervalMs = + (_c = options === null || options === void 0 ? void 0 : options.heartbeatIntervalMs) !== null && _c !== void 0 ? _c : CONNECTION_TIMEOUTS.HEARTBEAT_INTERVAL; + this.worker = (_d = options === null || options === void 0 ? void 0 : options.worker) !== null && _d !== void 0 ? _d : false; + this.accessToken = (_e = options === null || options === void 0 ? void 0 : options.accessToken) !== null && _e !== void 0 ? _e : null; + this.heartbeatCallback = (_f = options === null || options === void 0 ? void 0 : options.heartbeatCallback) !== null && _f !== void 0 ? _f : noop; + this.vsn = (_g = options === null || options === void 0 ? void 0 : options.vsn) !== null && _g !== void 0 ? _g : constants_1.DEFAULT_VSN; + // Handle special cases + if (options === null || options === void 0 ? void 0 : options.params) + this.params = options.params; + if (options === null || options === void 0 ? void 0 : options.logger) + this.logger = options.logger; + if ((options === null || options === void 0 ? void 0 : options.logLevel) || (options === null || options === void 0 ? void 0 : options.log_level)) { + this.logLevel = options.logLevel || options.log_level; + this.params = Object.assign(Object.assign({}, this.params), { log_level: this.logLevel }); + } + // Set up functions with defaults + this.reconnectAfterMs = + (_h = options === null || options === void 0 ? void 0 : options.reconnectAfterMs) !== null && _h !== void 0 ? _h : ((tries) => { + return RECONNECT_INTERVALS[tries - 1] || DEFAULT_RECONNECT_FALLBACK; + }); + switch (this.vsn) { + case constants_1.VSN_1_0_0: + this.encode = + (_j = options === null || options === void 0 ? void 0 : options.encode) !== null && _j !== void 0 ? _j : ((payload, callback) => { + return callback(JSON.stringify(payload)); + }); + this.decode = + (_k = options === null || options === void 0 ? void 0 : options.decode) !== null && _k !== void 0 ? _k : ((payload, callback) => { + return callback(JSON.parse(payload)); + }); + break; + case constants_1.VSN_2_0_0: + this.encode = (_l = options === null || options === void 0 ? void 0 : options.encode) !== null && _l !== void 0 ? _l : this.serializer.encode.bind(this.serializer); + this.decode = (_m = options === null || options === void 0 ? void 0 : options.decode) !== null && _m !== void 0 ? _m : this.serializer.decode.bind(this.serializer); + break; + default: + throw new Error(`Unsupported serializer version: ${this.vsn}`); + } + // Handle worker setup + if (this.worker) { + if (typeof window !== 'undefined' && !window.Worker) { + throw new Error('Web Worker is not supported'); + } + this.workerUrl = options === null || options === void 0 ? void 0 : options.workerUrl; + } + } +} +exports["default"] = RealtimeClient; +//# sourceMappingURL=RealtimeClient.js.map + +/***/ }), + +/***/ 5583: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +/* + This file draws heavily from https://github.com/phoenixframework/phoenix/blob/d344ec0a732ab4ee204215b31de69cf4be72e3bf/assets/js/phoenix/presence.js + License: https://github.com/phoenixframework/phoenix/blob/d344ec0a732ab4ee204215b31de69cf4be72e3bf/LICENSE.md +*/ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.REALTIME_PRESENCE_LISTEN_EVENTS = void 0; +var REALTIME_PRESENCE_LISTEN_EVENTS; +(function (REALTIME_PRESENCE_LISTEN_EVENTS) { + REALTIME_PRESENCE_LISTEN_EVENTS["SYNC"] = "sync"; + REALTIME_PRESENCE_LISTEN_EVENTS["JOIN"] = "join"; + REALTIME_PRESENCE_LISTEN_EVENTS["LEAVE"] = "leave"; +})(REALTIME_PRESENCE_LISTEN_EVENTS || (exports.REALTIME_PRESENCE_LISTEN_EVENTS = REALTIME_PRESENCE_LISTEN_EVENTS = {})); +class RealtimePresence { + /** + * Creates a Presence helper that keeps the local presence state in sync with the server. * - * @param options.verbose - If `true`, the query identifier will be returned - * and `data` will include the output columns of the query + * @param channel - The realtime channel to bind to. + * @param opts - Optional custom event names, e.g. `{ events: { state: 'state', diff: 'diff' } }`. * - * @param options.settings - If `true`, include information on configuration - * parameters that affect query planning + * @example + * ```ts + * const presence = new RealtimePresence(channel) * - * @param options.buffers - If `true`, include information on buffer usage + * channel.on('presence', ({ event, key }) => { + * console.log(`Presence ${event} on ${key}`) + * }) + * ``` + */ + constructor(channel, opts) { + this.channel = channel; + this.state = {}; + this.pendingDiffs = []; + this.joinRef = null; + this.enabled = false; + this.caller = { + onJoin: () => { }, + onLeave: () => { }, + onSync: () => { }, + }; + const events = (opts === null || opts === void 0 ? void 0 : opts.events) || { + state: 'presence_state', + diff: 'presence_diff', + }; + this.channel._on(events.state, {}, (newState) => { + const { onJoin, onLeave, onSync } = this.caller; + this.joinRef = this.channel._joinRef(); + this.state = RealtimePresence.syncState(this.state, newState, onJoin, onLeave); + this.pendingDiffs.forEach((diff) => { + this.state = RealtimePresence.syncDiff(this.state, diff, onJoin, onLeave); + }); + this.pendingDiffs = []; + onSync(); + }); + this.channel._on(events.diff, {}, (diff) => { + const { onJoin, onLeave, onSync } = this.caller; + if (this.inPendingSyncState()) { + this.pendingDiffs.push(diff); + } + else { + this.state = RealtimePresence.syncDiff(this.state, diff, onJoin, onLeave); + onSync(); + } + }); + this.onJoin((key, currentPresences, newPresences) => { + this.channel._trigger('presence', { + event: 'join', + key, + currentPresences, + newPresences, + }); + }); + this.onLeave((key, currentPresences, leftPresences) => { + this.channel._trigger('presence', { + event: 'leave', + key, + currentPresences, + leftPresences, + }); + }); + this.onSync(() => { + this.channel._trigger('presence', { event: 'sync' }); + }); + } + /** + * Used to sync the list of presences on the server with the + * client's state. * - * @param options.wal - If `true`, include information on WAL record generation + * An optional `onJoin` and `onLeave` callback can be provided to + * react to changes in the client's local presences across + * disconnects and reconnects with the server. * - * @param options.format - The format of the output, can be `"text"` (default) - * or `"json"` + * @internal */ - explain({ analyze = false, verbose = false, settings = false, buffers = false, wal = false, format = 'text', } = {}) { - const options = [ - analyze ? 'analyze' : null, - verbose ? 'verbose' : null, - settings ? 'settings' : null, - buffers ? 'buffers' : null, - wal ? 'wal' : null, - ] - .filter(Boolean) - .join('|'); - // An Accept header can carry multiple media types but postgrest-js always sends one - const forMediatype = this.headers['Accept']; - this.headers['Accept'] = `application/vnd.pgrst.plan+${format}; for="${forMediatype}"; options=${options};`; - if (format === 'json') - return this; - else - return this; + static syncState(currentState, newState, onJoin, onLeave) { + const state = this.cloneDeep(currentState); + const transformedState = this.transformState(newState); + const joins = {}; + const leaves = {}; + this.map(state, (key, presences) => { + if (!transformedState[key]) { + leaves[key] = presences; + } + }); + this.map(transformedState, (key, newPresences) => { + const currentPresences = state[key]; + if (currentPresences) { + const newPresenceRefs = newPresences.map((m) => m.presence_ref); + const curPresenceRefs = currentPresences.map((m) => m.presence_ref); + const joinedPresences = newPresences.filter((m) => curPresenceRefs.indexOf(m.presence_ref) < 0); + const leftPresences = currentPresences.filter((m) => newPresenceRefs.indexOf(m.presence_ref) < 0); + if (joinedPresences.length > 0) { + joins[key] = joinedPresences; + } + if (leftPresences.length > 0) { + leaves[key] = leftPresences; + } + } + else { + joins[key] = newPresences; + } + }); + return this.syncDiff(state, { joins, leaves }, onJoin, onLeave); } /** - * Rollback the query. + * Used to sync a diff of presence join and leave events from the + * server, as they happen. + * + * Like `syncState`, `syncDiff` accepts optional `onJoin` and + * `onLeave` callbacks to react to a user joining or leaving from a + * device. * - * `data` will still be returned, but the query is not committed. + * @internal */ - rollback() { - var _a; - if (((_a = this.headers['Prefer']) !== null && _a !== void 0 ? _a : '').trim().length > 0) { - this.headers['Prefer'] += ',tx=rollback'; + static syncDiff(state, diff, onJoin, onLeave) { + const { joins, leaves } = { + joins: this.transformState(diff.joins), + leaves: this.transformState(diff.leaves), + }; + if (!onJoin) { + onJoin = () => { }; } - else { - this.headers['Prefer'] = 'tx=rollback'; + if (!onLeave) { + onLeave = () => { }; } - return this; + this.map(joins, (key, newPresences) => { + var _a; + const currentPresences = (_a = state[key]) !== null && _a !== void 0 ? _a : []; + state[key] = this.cloneDeep(newPresences); + if (currentPresences.length > 0) { + const joinedPresenceRefs = state[key].map((m) => m.presence_ref); + const curPresences = currentPresences.filter((m) => joinedPresenceRefs.indexOf(m.presence_ref) < 0); + state[key].unshift(...curPresences); + } + onJoin(key, currentPresences, newPresences); + }); + this.map(leaves, (key, leftPresences) => { + let currentPresences = state[key]; + if (!currentPresences) + return; + const presenceRefsToRemove = leftPresences.map((m) => m.presence_ref); + currentPresences = currentPresences.filter((m) => presenceRefsToRemove.indexOf(m.presence_ref) < 0); + state[key] = currentPresences; + onLeave(key, currentPresences, leftPresences); + if (currentPresences.length === 0) + delete state[key]; + }); + return state; + } + /** @internal */ + static map(obj, func) { + return Object.getOwnPropertyNames(obj).map((key) => func(key, obj[key])); } /** - * Override the type of the returned `data`. + * Remove 'metas' key + * Change 'phx_ref' to 'presence_ref' + * Remove 'phx_ref' and 'phx_ref_prev' + * + * @example + * // returns { + * abc123: [ + * { presence_ref: '2', user_id: 1 }, + * { presence_ref: '3', user_id: 2 } + * ] + * } + * RealtimePresence.transformState({ + * abc123: { + * metas: [ + * { phx_ref: '2', phx_ref_prev: '1' user_id: 1 }, + * { phx_ref: '3', user_id: 2 } + * ] + * } + * }) * - * @typeParam NewResult - The new result type to override with + * @internal */ - returns() { - return this; + static transformState(state) { + state = this.cloneDeep(state); + return Object.getOwnPropertyNames(state).reduce((newState, key) => { + const presences = state[key]; + if ('metas' in presences) { + newState[key] = presences.metas.map((presence) => { + presence['presence_ref'] = presence['phx_ref']; + delete presence['phx_ref']; + delete presence['phx_ref_prev']; + return presence; + }); + } + else { + newState[key] = presences; + } + return newState; + }, {}); + } + /** @internal */ + static cloneDeep(obj) { + return JSON.parse(JSON.stringify(obj)); + } + /** @internal */ + onJoin(callback) { + this.caller.onJoin = callback; + } + /** @internal */ + onLeave(callback) { + this.caller.onLeave = callback; + } + /** @internal */ + onSync(callback) { + this.caller.onSync = callback; + } + /** @internal */ + inPendingSyncState() { + return !this.joinRef || this.joinRef !== this.channel._joinRef(); } } -exports["default"] = PostgrestTransformBuilder; -//# sourceMappingURL=PostgrestTransformBuilder.js.map +exports["default"] = RealtimePresence; +//# sourceMappingURL=RealtimePresence.js.map /***/ }), -/***/ 879: +/***/ 442: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; +var __webpack_unused_export__; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.DEFAULT_HEADERS = void 0; -const version_1 = __nccwpck_require__(3481); -exports.DEFAULT_HEADERS = { 'X-Client-Info': `postgrest-js/${version_1.version}` }; -//# sourceMappingURL=constants.js.map - -/***/ }), - -/***/ 720: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.PostgrestBuilder = exports.PostgrestTransformBuilder = exports.PostgrestFilterBuilder = exports.PostgrestQueryBuilder = exports.PostgrestClient = void 0; -var PostgrestClient_1 = __nccwpck_require__(8223); -Object.defineProperty(exports, "PostgrestClient", ({ enumerable: true, get: function () { return __importDefault(PostgrestClient_1).default; } })); -var PostgrestQueryBuilder_1 = __nccwpck_require__(5683); -Object.defineProperty(exports, "PostgrestQueryBuilder", ({ enumerable: true, get: function () { return __importDefault(PostgrestQueryBuilder_1).default; } })); -var PostgrestFilterBuilder_1 = __nccwpck_require__(1446); -Object.defineProperty(exports, "PostgrestFilterBuilder", ({ enumerable: true, get: function () { return __importDefault(PostgrestFilterBuilder_1).default; } })); -var PostgrestTransformBuilder_1 = __nccwpck_require__(39); -Object.defineProperty(exports, "PostgrestTransformBuilder", ({ enumerable: true, get: function () { return __importDefault(PostgrestTransformBuilder_1).default; } })); -var PostgrestBuilder_1 = __nccwpck_require__(9963); -Object.defineProperty(exports, "PostgrestBuilder", ({ enumerable: true, get: function () { return __importDefault(PostgrestBuilder_1).default; } })); +__webpack_unused_export__ = ({ value: true }); +__webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = exports.VH = __webpack_unused_export__ = __webpack_unused_export__ = void 0; +const tslib_1 = __nccwpck_require__(7647); +const RealtimeClient_1 = tslib_1.__importDefault(__nccwpck_require__(9103)); +exports.VH = RealtimeClient_1.default; +const RealtimeChannel_1 = tslib_1.__importStar(__nccwpck_require__(9911)); +__webpack_unused_export__ = RealtimeChannel_1.default; +__webpack_unused_export__ = ({ enumerable: true, get: function () { return RealtimeChannel_1.REALTIME_LISTEN_TYPES; } }); +__webpack_unused_export__ = ({ enumerable: true, get: function () { return RealtimeChannel_1.REALTIME_POSTGRES_CHANGES_LISTEN_EVENT; } }); +__webpack_unused_export__ = ({ enumerable: true, get: function () { return RealtimeChannel_1.REALTIME_SUBSCRIBE_STATES; } }); +__webpack_unused_export__ = ({ enumerable: true, get: function () { return RealtimeChannel_1.REALTIME_CHANNEL_STATES; } }); +const RealtimePresence_1 = tslib_1.__importStar(__nccwpck_require__(5583)); +__webpack_unused_export__ = RealtimePresence_1.default; +__webpack_unused_export__ = ({ enumerable: true, get: function () { return RealtimePresence_1.REALTIME_PRESENCE_LISTEN_EVENTS; } }); +const websocket_factory_1 = tslib_1.__importDefault(__nccwpck_require__(3478)); +__webpack_unused_export__ = websocket_factory_1.default; //# sourceMappingURL=index.js.map /***/ }), -/***/ 3481: -/***/ ((__unused_webpack_module, exports) => { +/***/ 88: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.version = void 0; -exports.version = '1.8.5'; -//# sourceMappingURL=version.js.map - -/***/ }), - -/***/ 9911: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +exports.CONNECTION_STATE = exports.TRANSPORTS = exports.CHANNEL_EVENTS = exports.CHANNEL_STATES = exports.SOCKET_STATES = exports.MAX_PUSH_BUFFER_SIZE = exports.WS_CLOSE_NORMAL = exports.DEFAULT_TIMEOUT = exports.VERSION = exports.DEFAULT_VSN = exports.VSN_2_0_0 = exports.VSN_1_0_0 = exports.DEFAULT_VERSION = void 0; +const version_1 = __nccwpck_require__(318); +exports.DEFAULT_VERSION = `realtime-js/${version_1.version}`; +exports.VSN_1_0_0 = '1.0.0'; +exports.VSN_2_0_0 = '2.0.0'; +exports.DEFAULT_VSN = exports.VSN_2_0_0; +exports.VERSION = version_1.version; +exports.DEFAULT_TIMEOUT = 10000; +exports.WS_CLOSE_NORMAL = 1000; +exports.MAX_PUSH_BUFFER_SIZE = 100; +var SOCKET_STATES; +(function (SOCKET_STATES) { + SOCKET_STATES[SOCKET_STATES["connecting"] = 0] = "connecting"; + SOCKET_STATES[SOCKET_STATES["open"] = 1] = "open"; + SOCKET_STATES[SOCKET_STATES["closing"] = 2] = "closing"; + SOCKET_STATES[SOCKET_STATES["closed"] = 3] = "closed"; +})(SOCKET_STATES || (exports.SOCKET_STATES = SOCKET_STATES = {})); +var CHANNEL_STATES; +(function (CHANNEL_STATES) { + CHANNEL_STATES["closed"] = "closed"; + CHANNEL_STATES["errored"] = "errored"; + CHANNEL_STATES["joined"] = "joined"; + CHANNEL_STATES["joining"] = "joining"; + CHANNEL_STATES["leaving"] = "leaving"; +})(CHANNEL_STATES || (exports.CHANNEL_STATES = CHANNEL_STATES = {})); +var CHANNEL_EVENTS; +(function (CHANNEL_EVENTS) { + CHANNEL_EVENTS["close"] = "phx_close"; + CHANNEL_EVENTS["error"] = "phx_error"; + CHANNEL_EVENTS["join"] = "phx_join"; + CHANNEL_EVENTS["reply"] = "phx_reply"; + CHANNEL_EVENTS["leave"] = "phx_leave"; + CHANNEL_EVENTS["access_token"] = "access_token"; +})(CHANNEL_EVENTS || (exports.CHANNEL_EVENTS = CHANNEL_EVENTS = {})); +var TRANSPORTS; +(function (TRANSPORTS) { + TRANSPORTS["websocket"] = "websocket"; +})(TRANSPORTS || (exports.TRANSPORTS = TRANSPORTS = {})); +var CONNECTION_STATE; +(function (CONNECTION_STATE) { + CONNECTION_STATE["Connecting"] = "connecting"; + CONNECTION_STATE["Open"] = "open"; + CONNECTION_STATE["Closing"] = "closing"; + CONNECTION_STATE["Closed"] = "closed"; +})(CONNECTION_STATE || (exports.CONNECTION_STATE = CONNECTION_STATE = {})); +//# sourceMappingURL=constants.js.map + +/***/ }), + +/***/ 2292: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.REALTIME_CHANNEL_STATES = exports.REALTIME_SUBSCRIBE_STATES = exports.REALTIME_LISTEN_TYPES = exports.REALTIME_POSTGRES_CHANGES_LISTEN_EVENT = void 0; const constants_1 = __nccwpck_require__(88); -const push_1 = __importDefault(__nccwpck_require__(2292)); -const timer_1 = __importDefault(__nccwpck_require__(2983)); -const RealtimePresence_1 = __importDefault(__nccwpck_require__(5583)); -const Transformers = __importStar(__nccwpck_require__(1140)); -var REALTIME_POSTGRES_CHANGES_LISTEN_EVENT; -(function (REALTIME_POSTGRES_CHANGES_LISTEN_EVENT) { - REALTIME_POSTGRES_CHANGES_LISTEN_EVENT["ALL"] = "*"; - REALTIME_POSTGRES_CHANGES_LISTEN_EVENT["INSERT"] = "INSERT"; - REALTIME_POSTGRES_CHANGES_LISTEN_EVENT["UPDATE"] = "UPDATE"; - REALTIME_POSTGRES_CHANGES_LISTEN_EVENT["DELETE"] = "DELETE"; -})(REALTIME_POSTGRES_CHANGES_LISTEN_EVENT = exports.REALTIME_POSTGRES_CHANGES_LISTEN_EVENT || (exports.REALTIME_POSTGRES_CHANGES_LISTEN_EVENT = {})); -var REALTIME_LISTEN_TYPES; -(function (REALTIME_LISTEN_TYPES) { - REALTIME_LISTEN_TYPES["BROADCAST"] = "broadcast"; - REALTIME_LISTEN_TYPES["PRESENCE"] = "presence"; +class Push { /** - * listen to Postgres changes. + * Initializes the Push + * + * @param channel The Channel + * @param event The event, for example `"phx_join"` + * @param payload The payload, for example `{user_id: 123}` + * @param timeout The push timeout in milliseconds */ - REALTIME_LISTEN_TYPES["POSTGRES_CHANGES"] = "postgres_changes"; -})(REALTIME_LISTEN_TYPES = exports.REALTIME_LISTEN_TYPES || (exports.REALTIME_LISTEN_TYPES = {})); -var REALTIME_SUBSCRIBE_STATES; -(function (REALTIME_SUBSCRIBE_STATES) { - REALTIME_SUBSCRIBE_STATES["SUBSCRIBED"] = "SUBSCRIBED"; - REALTIME_SUBSCRIBE_STATES["TIMED_OUT"] = "TIMED_OUT"; - REALTIME_SUBSCRIBE_STATES["CLOSED"] = "CLOSED"; - REALTIME_SUBSCRIBE_STATES["CHANNEL_ERROR"] = "CHANNEL_ERROR"; -})(REALTIME_SUBSCRIBE_STATES = exports.REALTIME_SUBSCRIBE_STATES || (exports.REALTIME_SUBSCRIBE_STATES = {})); -exports.REALTIME_CHANNEL_STATES = constants_1.CHANNEL_STATES; -/** A channel is the basic building block of Realtime - * and narrows the scope of data flow to subscribed clients. - * You can think of a channel as a chatroom where participants are able to see who's online - * and send and receive messages. - */ -class RealtimeChannel { - constructor( - /** Topic name can be any string. */ - topic, params = { config: {} }, socket) { - this.topic = topic; - this.params = params; - this.socket = socket; - this.bindings = {}; - this.state = constants_1.CHANNEL_STATES.closed; - this.joinedOnce = false; - this.pushBuffer = []; - this.subTopic = topic.replace(/^realtime:/i, ''); - this.params.config = Object.assign({ - broadcast: { ack: false, self: false }, - presence: { key: '' }, - }, params.config); - this.timeout = this.socket.timeout; - this.joinPush = new push_1.default(this, constants_1.CHANNEL_EVENTS.join, this.params, this.timeout); - this.rejoinTimer = new timer_1.default(() => this._rejoinUntilConnected(), this.socket.reconnectAfterMs); - this.joinPush.receive('ok', () => { - this.state = constants_1.CHANNEL_STATES.joined; - this.rejoinTimer.reset(); - this.pushBuffer.forEach((pushEvent) => pushEvent.send()); - this.pushBuffer = []; - }); - this._onClose(() => { - this.rejoinTimer.reset(); - this.socket.log('channel', `close ${this.topic} ${this._joinRef()}`); - this.state = constants_1.CHANNEL_STATES.closed; - this.socket._remove(this); - }); - this._onError((reason) => { - if (this._isLeaving() || this._isClosed()) { - return; - } - this.socket.log('channel', `error ${this.topic}`, reason); - this.state = constants_1.CHANNEL_STATES.errored; - this.rejoinTimer.scheduleTimeout(); - }); - this.joinPush.receive('timeout', () => { - if (!this._isJoining()) { - return; - } - this.socket.log('channel', `timeout ${this.topic}`, this.joinPush.timeout); - this.state = constants_1.CHANNEL_STATES.errored; - this.rejoinTimer.scheduleTimeout(); - }); - this._on(constants_1.CHANNEL_EVENTS.reply, {}, (payload, ref) => { - this._trigger(this._replyEventName(ref), payload); - }); - this.presence = new RealtimePresence_1.default(this); - this.broadcastEndpointURL = this._broadcastEndpointURL(); - } - /** Subscribe registers your client with the server */ - subscribe(callback, timeout = this.timeout) { - var _a, _b; - if (!this.socket.isConnected()) { - this.socket.connect(); - } - if (this.joinedOnce) { - throw `tried to subscribe multiple times. 'subscribe' can only be called a single time per channel instance`; - } - else { - const { config: { broadcast, presence }, } = this.params; - this._onError((e) => callback && callback('CHANNEL_ERROR', e)); - this._onClose(() => callback && callback('CLOSED')); - const accessTokenPayload = {}; - const config = { - broadcast, - presence, - postgres_changes: (_b = (_a = this.bindings.postgres_changes) === null || _a === void 0 ? void 0 : _a.map((r) => r.filter)) !== null && _b !== void 0 ? _b : [], - }; - if (this.socket.accessToken) { - accessTokenPayload.access_token = this.socket.accessToken; - } - this.updateJoinPayload(Object.assign({ config }, accessTokenPayload)); - this.joinedOnce = true; - this._rejoin(timeout); - this.joinPush - .receive('ok', ({ postgres_changes: serverPostgresFilters, }) => { - var _a; - this.socket.accessToken && - this.socket.setAuth(this.socket.accessToken); - if (serverPostgresFilters === undefined) { - callback && callback('SUBSCRIBED'); - return; - } - else { - const clientPostgresBindings = this.bindings.postgres_changes; - const bindingsLen = (_a = clientPostgresBindings === null || clientPostgresBindings === void 0 ? void 0 : clientPostgresBindings.length) !== null && _a !== void 0 ? _a : 0; - const newPostgresBindings = []; - for (let i = 0; i < bindingsLen; i++) { - const clientPostgresBinding = clientPostgresBindings[i]; - const { filter: { event, schema, table, filter }, } = clientPostgresBinding; - const serverPostgresFilter = serverPostgresFilters && serverPostgresFilters[i]; - if (serverPostgresFilter && - serverPostgresFilter.event === event && - serverPostgresFilter.schema === schema && - serverPostgresFilter.table === table && - serverPostgresFilter.filter === filter) { - newPostgresBindings.push(Object.assign(Object.assign({}, clientPostgresBinding), { id: serverPostgresFilter.id })); - } - else { - this.unsubscribe(); - callback && - callback('CHANNEL_ERROR', new Error('mismatch between server and client bindings for postgres changes')); - return; - } - } - this.bindings.postgres_changes = newPostgresBindings; - callback && callback('SUBSCRIBED'); - return; - } - }) - .receive('error', (error) => { - callback && - callback('CHANNEL_ERROR', new Error(JSON.stringify(Object.values(error).join(', ') || 'error'))); - return; - }) - .receive('timeout', () => { - callback && callback('TIMED_OUT'); - return; - }); - } - return this; - } - presenceState() { - return this.presence.state; + constructor(channel, event, payload = {}, timeout = constants_1.DEFAULT_TIMEOUT) { + this.channel = channel; + this.event = event; + this.payload = payload; + this.timeout = timeout; + this.sent = false; + this.timeoutTimer = undefined; + this.ref = ''; + this.receivedResp = null; + this.recHooks = []; + this.refEvent = null; } - async track(payload, opts = {}) { - return await this.send({ - type: 'presence', - event: 'track', - payload, - }, opts.timeout || this.timeout); + resend(timeout) { + this.timeout = timeout; + this._cancelRefEvent(); + this.ref = ''; + this.refEvent = null; + this.receivedResp = null; + this.sent = false; + this.send(); } - async untrack(opts = {}) { - return await this.send({ - type: 'presence', - event: 'untrack', - }, opts); + send() { + if (this._hasReceived('timeout')) { + return; + } + this.startTimeout(); + this.sent = true; + this.channel.socket.push({ + topic: this.channel.topic, + event: this.event, + payload: this.payload, + ref: this.ref, + join_ref: this.channel._joinRef(), + }); } - on(type, filter, callback) { - return this._on(type, filter, callback); + updatePayload(payload) { + this.payload = Object.assign(Object.assign({}, this.payload), payload); } - /** - * Sends a message into the channel. - * - * @param args Arguments to send to channel - * @param args.type The type of event to send - * @param args.event The name of the event being sent - * @param args.payload Payload to be sent - * @param opts Options to be used during the send process - */ - async send(args, opts = {}) { - var _a, _b; - if (!this._canPush() && args.type === 'broadcast') { - const { event, payload: endpoint_payload } = args; - const options = { - method: 'POST', - headers: { - apikey: (_a = this.socket.accessToken) !== null && _a !== void 0 ? _a : '', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - messages: [ - { topic: this.subTopic, event, payload: endpoint_payload }, - ], - }), - }; - try { - const response = await this._fetchWithTimeout(this.broadcastEndpointURL, options, (_b = opts.timeout) !== null && _b !== void 0 ? _b : this.timeout); - if (response.ok) { - return 'ok'; - } - else { - return 'error'; - } - } - catch (error) { - if (error.name === 'AbortError') { - return 'timed out'; - } - else { - return 'error'; - } - } - } - else { - return new Promise((resolve) => { - var _a, _b, _c; - const push = this._push(args.type, args, opts.timeout || this.timeout); - if (args.type === 'broadcast' && !((_c = (_b = (_a = this.params) === null || _a === void 0 ? void 0 : _a.config) === null || _b === void 0 ? void 0 : _b.broadcast) === null || _c === void 0 ? void 0 : _c.ack)) { - resolve('ok'); - } - push.receive('ok', () => resolve('ok')); - push.receive('timeout', () => resolve('timed out')); - }); + receive(status, callback) { + var _a; + if (this._hasReceived(status)) { + callback((_a = this.receivedResp) === null || _a === void 0 ? void 0 : _a.response); } + this.recHooks.push({ status, callback }); + return this; } - updateJoinPayload(payload) { - this.joinPush.updatePayload(payload); - } - /** - * Leaves the channel. - * - * Unsubscribes from server events, and instructs channel to terminate on server. - * Triggers onClose() hooks. - * - * To receive leave acknowledgements, use the a `receive` hook to bind to the server ack, ie: - * channel.unsubscribe().receive("ok", () => alert("left!") ) - */ - unsubscribe(timeout = this.timeout) { - this.state = constants_1.CHANNEL_STATES.leaving; - const onClose = () => { - this.socket.log('channel', `leave ${this.topic}`); - this._trigger(constants_1.CHANNEL_EVENTS.close, 'leave', this._joinRef()); + startTimeout() { + if (this.timeoutTimer) { + return; + } + this.ref = this.channel.socket._makeRef(); + this.refEvent = this.channel._replyEventName(this.ref); + const callback = (payload) => { + this._cancelRefEvent(); + this._cancelTimeout(); + this.receivedResp = payload; + this._matchReceive(payload); }; - this.rejoinTimer.reset(); - // Destroy joinPush to avoid connection timeouts during unscription phase - this.joinPush.destroy(); - return new Promise((resolve) => { - const leavePush = new push_1.default(this, constants_1.CHANNEL_EVENTS.leave, {}, timeout); - leavePush - .receive('ok', () => { - onClose(); - resolve('ok'); - }) - .receive('timeout', () => { - onClose(); - resolve('timed out'); - }) - .receive('error', () => { - resolve('error'); - }); - leavePush.send(); - if (!this._canPush()) { - leavePush.trigger('ok', {}); - } - }); + this.channel._on(this.refEvent, {}, callback); + this.timeoutTimer = setTimeout(() => { + this.trigger('timeout', {}); + }, this.timeout); } - /** @internal */ - _broadcastEndpointURL() { - let url = this.socket.endPoint; - url = url.replace(/^ws/i, 'http'); - url = url.replace(/(\/socket\/websocket|\/socket|\/websocket)\/?$/i, ''); - return url.replace(/\/+$/, '') + '/api/broadcast'; + trigger(status, response) { + if (this.refEvent) + this.channel._trigger(this.refEvent, { status, response }); } - async _fetchWithTimeout(url, options, timeout) { - const controller = new AbortController(); - const id = setTimeout(() => controller.abort(), timeout); - const response = await this.socket.fetch(url, Object.assign(Object.assign({}, options), { signal: controller.signal })); - clearTimeout(id); - return response; + destroy() { + this._cancelRefEvent(); + this._cancelTimeout(); } - /** @internal */ - _push(event, payload, timeout = this.timeout) { - if (!this.joinedOnce) { - throw `tried to push '${event}' to '${this.topic}' before joining. Use channel.subscribe() before pushing events`; - } - let pushEvent = new push_1.default(this, event, payload, timeout); - if (this._canPush()) { - pushEvent.send(); - } - else { - pushEvent.startTimeout(); - this.pushBuffer.push(pushEvent); + _cancelRefEvent() { + if (!this.refEvent) { + return; } - return pushEvent; + this.channel._off(this.refEvent, {}); } - /** - * Overridable message hook - * - * Receives all events for specialized message handling before dispatching to the channel callbacks. - * Must return the payload, modified or unmodified. - * - * @internal - */ - _onMessage(_event, payload, _ref) { - return payload; + _cancelTimeout() { + clearTimeout(this.timeoutTimer); + this.timeoutTimer = undefined; } - /** @internal */ - _isMember(topic) { - return this.topic === topic; + _matchReceive({ status, response }) { + this.recHooks.filter((h) => h.status === status).forEach((h) => h.callback(response)); } - /** @internal */ - _joinRef() { - return this.joinPush.ref; + _hasReceived(status) { + return this.receivedResp && this.receivedResp.status === status; } - /** @internal */ - _trigger(type, payload, ref) { - var _a, _b; - const typeLower = type.toLocaleLowerCase(); - const { close, error, leave, join } = constants_1.CHANNEL_EVENTS; - const events = [close, error, leave, join]; - if (ref && events.indexOf(typeLower) >= 0 && ref !== this._joinRef()) { - return; - } - let handledPayload = this._onMessage(typeLower, payload, ref); - if (payload && !handledPayload) { - throw 'channel onMessage callbacks must return the payload, modified or unmodified'; - } - if (['insert', 'update', 'delete'].includes(typeLower)) { - (_a = this.bindings.postgres_changes) === null || _a === void 0 ? void 0 : _a.filter((bind) => { - var _a, _b, _c; - return (((_a = bind.filter) === null || _a === void 0 ? void 0 : _a.event) === '*' || - ((_c = (_b = bind.filter) === null || _b === void 0 ? void 0 : _b.event) === null || _c === void 0 ? void 0 : _c.toLocaleLowerCase()) === typeLower); - }).map((bind) => bind.callback(handledPayload, ref)); +} +exports["default"] = Push; +//# sourceMappingURL=push.js.map + +/***/ }), + +/***/ 5360: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +class Serializer { + constructor(allowedMetadataKeys) { + this.HEADER_LENGTH = 1; + this.USER_BROADCAST_PUSH_META_LENGTH = 6; + this.KINDS = { userBroadcastPush: 3, userBroadcast: 4 }; + this.BINARY_ENCODING = 0; + this.JSON_ENCODING = 1; + this.BROADCAST_EVENT = 'broadcast'; + this.allowedMetadataKeys = []; + this.allowedMetadataKeys = allowedMetadataKeys !== null && allowedMetadataKeys !== void 0 ? allowedMetadataKeys : []; + } + encode(msg, callback) { + if (msg.event === this.BROADCAST_EVENT && + !(msg.payload instanceof ArrayBuffer) && + typeof msg.payload.event === 'string') { + return callback(this._binaryEncodeUserBroadcastPush(msg)); + } + let payload = [msg.join_ref, msg.ref, msg.topic, msg.event, msg.payload]; + return callback(JSON.stringify(payload)); + } + _binaryEncodeUserBroadcastPush(message) { + var _a; + if (this._isArrayBuffer((_a = message.payload) === null || _a === void 0 ? void 0 : _a.payload)) { + return this._encodeBinaryUserBroadcastPush(message); } else { - (_b = this.bindings[typeLower]) === null || _b === void 0 ? void 0 : _b.filter((bind) => { - var _a, _b, _c, _d, _e, _f; - if (['broadcast', 'presence', 'postgres_changes'].includes(typeLower)) { - if ('id' in bind) { - const bindId = bind.id; - const bindEvent = (_a = bind.filter) === null || _a === void 0 ? void 0 : _a.event; - return (bindId && - ((_b = payload.ids) === null || _b === void 0 ? void 0 : _b.includes(bindId)) && - (bindEvent === '*' || - (bindEvent === null || bindEvent === void 0 ? void 0 : bindEvent.toLocaleLowerCase()) === - ((_c = payload.data) === null || _c === void 0 ? void 0 : _c.type.toLocaleLowerCase()))); - } - else { - const bindEvent = (_e = (_d = bind === null || bind === void 0 ? void 0 : bind.filter) === null || _d === void 0 ? void 0 : _d.event) === null || _e === void 0 ? void 0 : _e.toLocaleLowerCase(); - return (bindEvent === '*' || - bindEvent === ((_f = payload === null || payload === void 0 ? void 0 : payload.event) === null || _f === void 0 ? void 0 : _f.toLocaleLowerCase())); - } - } - else { - return bind.type.toLocaleLowerCase() === typeLower; - } - }).map((bind) => { - if (typeof handledPayload === 'object' && 'ids' in handledPayload) { - const postgresChanges = handledPayload.data; - const { schema, table, commit_timestamp, type, errors } = postgresChanges; - const enrichedPayload = { - schema: schema, - table: table, - commit_timestamp: commit_timestamp, - eventType: type, - new: {}, - old: {}, - errors: errors, - }; - handledPayload = Object.assign(Object.assign({}, enrichedPayload), this._getPayloadRecords(postgresChanges)); - } - bind.callback(handledPayload, ref); - }); + return this._encodeJsonUserBroadcastPush(message); } } - /** @internal */ - _isClosed() { - return this.state === constants_1.CHANNEL_STATES.closed; + _encodeBinaryUserBroadcastPush(message) { + var _a, _b; + const userPayload = (_b = (_a = message.payload) === null || _a === void 0 ? void 0 : _a.payload) !== null && _b !== void 0 ? _b : new ArrayBuffer(0); + return this._encodeUserBroadcastPush(message, this.BINARY_ENCODING, userPayload); } - /** @internal */ - _isJoined() { - return this.state === constants_1.CHANNEL_STATES.joined; + _encodeJsonUserBroadcastPush(message) { + var _a, _b; + const userPayload = (_b = (_a = message.payload) === null || _a === void 0 ? void 0 : _a.payload) !== null && _b !== void 0 ? _b : {}; + const encoder = new TextEncoder(); + const encodedUserPayload = encoder.encode(JSON.stringify(userPayload)).buffer; + return this._encodeUserBroadcastPush(message, this.JSON_ENCODING, encodedUserPayload); } - /** @internal */ - _isJoining() { - return this.state === constants_1.CHANNEL_STATES.joining; + _encodeUserBroadcastPush(message, encodingType, encodedPayload) { + var _a, _b; + const topic = message.topic; + const ref = (_a = message.ref) !== null && _a !== void 0 ? _a : ''; + const joinRef = (_b = message.join_ref) !== null && _b !== void 0 ? _b : ''; + const userEvent = message.payload.event; + // Filter metadata based on allowed keys + const rest = this.allowedMetadataKeys + ? this._pick(message.payload, this.allowedMetadataKeys) + : {}; + const metadata = Object.keys(rest).length === 0 ? '' : JSON.stringify(rest); + // Validate lengths don't exceed uint8 max value (255) + if (joinRef.length > 255) { + throw new Error(`joinRef length ${joinRef.length} exceeds maximum of 255`); + } + if (ref.length > 255) { + throw new Error(`ref length ${ref.length} exceeds maximum of 255`); + } + if (topic.length > 255) { + throw new Error(`topic length ${topic.length} exceeds maximum of 255`); + } + if (userEvent.length > 255) { + throw new Error(`userEvent length ${userEvent.length} exceeds maximum of 255`); + } + if (metadata.length > 255) { + throw new Error(`metadata length ${metadata.length} exceeds maximum of 255`); + } + const metaLength = this.USER_BROADCAST_PUSH_META_LENGTH + + joinRef.length + + ref.length + + topic.length + + userEvent.length + + metadata.length; + const header = new ArrayBuffer(this.HEADER_LENGTH + metaLength); + let view = new DataView(header); + let offset = 0; + view.setUint8(offset++, this.KINDS.userBroadcastPush); // kind + view.setUint8(offset++, joinRef.length); + view.setUint8(offset++, ref.length); + view.setUint8(offset++, topic.length); + view.setUint8(offset++, userEvent.length); + view.setUint8(offset++, metadata.length); + view.setUint8(offset++, encodingType); + Array.from(joinRef, (char) => view.setUint8(offset++, char.charCodeAt(0))); + Array.from(ref, (char) => view.setUint8(offset++, char.charCodeAt(0))); + Array.from(topic, (char) => view.setUint8(offset++, char.charCodeAt(0))); + Array.from(userEvent, (char) => view.setUint8(offset++, char.charCodeAt(0))); + Array.from(metadata, (char) => view.setUint8(offset++, char.charCodeAt(0))); + var combined = new Uint8Array(header.byteLength + encodedPayload.byteLength); + combined.set(new Uint8Array(header), 0); + combined.set(new Uint8Array(encodedPayload), header.byteLength); + return combined.buffer; } - /** @internal */ - _isLeaving() { - return this.state === constants_1.CHANNEL_STATES.leaving; + decode(rawPayload, callback) { + if (this._isArrayBuffer(rawPayload)) { + let result = this._binaryDecode(rawPayload); + return callback(result); + } + if (typeof rawPayload === 'string') { + const jsonPayload = JSON.parse(rawPayload); + const [join_ref, ref, topic, event, payload] = jsonPayload; + return callback({ join_ref, ref, topic, event, payload }); + } + return callback({}); } - /** @internal */ - _replyEventName(ref) { - return `chan_reply_${ref}`; + _binaryDecode(buffer) { + const view = new DataView(buffer); + const kind = view.getUint8(0); + const decoder = new TextDecoder(); + switch (kind) { + case this.KINDS.userBroadcast: + return this._decodeUserBroadcast(buffer, view, decoder); + } } - /** @internal */ - _on(type, filter, callback) { - const typeLower = type.toLocaleLowerCase(); - const binding = { - type: typeLower, - filter: filter, - callback: callback, + _decodeUserBroadcast(buffer, view, decoder) { + const topicSize = view.getUint8(1); + const userEventSize = view.getUint8(2); + const metadataSize = view.getUint8(3); + const payloadEncoding = view.getUint8(4); + let offset = this.HEADER_LENGTH + 4; + const topic = decoder.decode(buffer.slice(offset, offset + topicSize)); + offset = offset + topicSize; + const userEvent = decoder.decode(buffer.slice(offset, offset + userEventSize)); + offset = offset + userEventSize; + const metadata = decoder.decode(buffer.slice(offset, offset + metadataSize)); + offset = offset + metadataSize; + const payload = buffer.slice(offset, buffer.byteLength); + const parsedPayload = payloadEncoding === this.JSON_ENCODING ? JSON.parse(decoder.decode(payload)) : payload; + const data = { + type: this.BROADCAST_EVENT, + event: userEvent, + payload: parsedPayload, }; - if (this.bindings[typeLower]) { - this.bindings[typeLower].push(binding); - } - else { - this.bindings[typeLower] = [binding]; + // Metadata is optional and always JSON encoded + if (metadataSize > 0) { + data['meta'] = JSON.parse(metadata); } - return this; + return { join_ref: null, ref: null, topic: topic, event: this.BROADCAST_EVENT, payload: data }; } - /** @internal */ - _off(type, filter) { - const typeLower = type.toLocaleLowerCase(); - this.bindings[typeLower] = this.bindings[typeLower].filter((bind) => { - var _a; - return !(((_a = bind.type) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase()) === typeLower && - RealtimeChannel.isEqual(bind.filter, filter)); - }); - return this; + _isArrayBuffer(buffer) { + var _a; + return buffer instanceof ArrayBuffer || ((_a = buffer === null || buffer === void 0 ? void 0 : buffer.constructor) === null || _a === void 0 ? void 0 : _a.name) === 'ArrayBuffer'; } - /** @internal */ - static isEqual(obj1, obj2) { - if (Object.keys(obj1).length !== Object.keys(obj2).length) { - return false; + _pick(obj, keys) { + if (!obj || typeof obj !== 'object') { + return {}; } - for (const k in obj1) { - if (obj1[k] !== obj2[k]) { - return false; - } - } - return true; + return Object.fromEntries(Object.entries(obj).filter(([key]) => keys.includes(key))); } - /** @internal */ - _rejoinUntilConnected() { - this.rejoinTimer.scheduleTimeout(); - if (this.socket.isConnected()) { - this._rejoin(); - } +} +exports["default"] = Serializer; +//# sourceMappingURL=serializer.js.map + +/***/ }), + +/***/ 2983: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * Creates a timer that accepts a `timerCalc` function to perform calculated timeout retries, such as exponential backoff. + * + * @example + * let reconnectTimer = new Timer(() => this.connect(), function(tries){ + * return [1000, 5000, 10000][tries - 1] || 10000 + * }) + * reconnectTimer.scheduleTimeout() // fires after 1000 + * reconnectTimer.scheduleTimeout() // fires after 5000 + * reconnectTimer.reset() + * reconnectTimer.scheduleTimeout() // fires after 1000 + */ +class Timer { + constructor(callback, timerCalc) { + this.callback = callback; + this.timerCalc = timerCalc; + this.timer = undefined; + this.tries = 0; + this.callback = callback; + this.timerCalc = timerCalc; } - /** - * Registers a callback that will be executed when the channel closes. - * - * @internal - */ - _onClose(callback) { - this._on(constants_1.CHANNEL_EVENTS.close, {}, callback); + reset() { + this.tries = 0; + clearTimeout(this.timer); + this.timer = undefined; } - /** - * Registers a callback that will be executed when the channel encounteres an error. - * - * @internal - */ - _onError(callback) { - this._on(constants_1.CHANNEL_EVENTS.error, {}, (reason) => callback(reason)); + // Cancels any previous scheduleTimeout and schedules callback + scheduleTimeout() { + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.tries = this.tries + 1; + this.callback(); + }, this.timerCalc(this.tries + 1)); } - /** - * Returns `true` if the socket is connected and the channel has been joined. - * - * @internal - */ - _canPush() { - return this.socket.isConnected() && this._isJoined(); +} +exports["default"] = Timer; +//# sourceMappingURL=timer.js.map + +/***/ }), + +/***/ 1140: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +/** + * Helpers to convert the change Payload into native JS types. + */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.httpEndpointURL = exports.toTimestampString = exports.toArray = exports.toJson = exports.toNumber = exports.toBoolean = exports.convertCell = exports.convertColumn = exports.convertChangeData = exports.PostgresTypes = void 0; +// Adapted from epgsql (src/epgsql_binary.erl), this module licensed under +// 3-clause BSD found here: https://raw.githubusercontent.com/epgsql/epgsql/devel/LICENSE +var PostgresTypes; +(function (PostgresTypes) { + PostgresTypes["abstime"] = "abstime"; + PostgresTypes["bool"] = "bool"; + PostgresTypes["date"] = "date"; + PostgresTypes["daterange"] = "daterange"; + PostgresTypes["float4"] = "float4"; + PostgresTypes["float8"] = "float8"; + PostgresTypes["int2"] = "int2"; + PostgresTypes["int4"] = "int4"; + PostgresTypes["int4range"] = "int4range"; + PostgresTypes["int8"] = "int8"; + PostgresTypes["int8range"] = "int8range"; + PostgresTypes["json"] = "json"; + PostgresTypes["jsonb"] = "jsonb"; + PostgresTypes["money"] = "money"; + PostgresTypes["numeric"] = "numeric"; + PostgresTypes["oid"] = "oid"; + PostgresTypes["reltime"] = "reltime"; + PostgresTypes["text"] = "text"; + PostgresTypes["time"] = "time"; + PostgresTypes["timestamp"] = "timestamp"; + PostgresTypes["timestamptz"] = "timestamptz"; + PostgresTypes["timetz"] = "timetz"; + PostgresTypes["tsrange"] = "tsrange"; + PostgresTypes["tstzrange"] = "tstzrange"; +})(PostgresTypes || (exports.PostgresTypes = PostgresTypes = {})); +/** + * Takes an array of columns and an object of string values then converts each string value + * to its mapped type. + * + * @param {{name: String, type: String}[]} columns + * @param {Object} record + * @param {Object} options The map of various options that can be applied to the mapper + * @param {Array} options.skipTypes The array of types that should not be converted + * + * @example convertChangeData([{name: 'first_name', type: 'text'}, {name: 'age', type: 'int4'}], {first_name: 'Paul', age:'33'}, {}) + * //=>{ first_name: 'Paul', age: 33 } + */ +const convertChangeData = (columns, record, options = {}) => { + var _a; + const skipTypes = (_a = options.skipTypes) !== null && _a !== void 0 ? _a : []; + if (!record) { + return {}; } - /** @internal */ - _rejoin(timeout = this.timeout) { - if (this._isLeaving()) { - return; + return Object.keys(record).reduce((acc, rec_key) => { + acc[rec_key] = (0, exports.convertColumn)(rec_key, columns, record, skipTypes); + return acc; + }, {}); +}; +exports.convertChangeData = convertChangeData; +/** + * Converts the value of an individual column. + * + * @param {String} columnName The column that you want to convert + * @param {{name: String, type: String}[]} columns All of the columns + * @param {Object} record The map of string values + * @param {Array} skipTypes An array of types that should not be converted + * @return {object} Useless information + * + * @example convertColumn('age', [{name: 'first_name', type: 'text'}, {name: 'age', type: 'int4'}], {first_name: 'Paul', age: '33'}, []) + * //=> 33 + * @example convertColumn('age', [{name: 'first_name', type: 'text'}, {name: 'age', type: 'int4'}], {first_name: 'Paul', age: '33'}, ['int4']) + * //=> "33" + */ +const convertColumn = (columnName, columns, record, skipTypes) => { + const column = columns.find((x) => x.name === columnName); + const colType = column === null || column === void 0 ? void 0 : column.type; + const value = record[columnName]; + if (colType && !skipTypes.includes(colType)) { + return (0, exports.convertCell)(colType, value); + } + return noop(value); +}; +exports.convertColumn = convertColumn; +/** + * If the value of the cell is `null`, returns null. + * Otherwise converts the string value to the correct type. + * @param {String} type A postgres column type + * @param {String} value The cell value + * + * @example convertCell('bool', 't') + * //=> true + * @example convertCell('int8', '10') + * //=> 10 + * @example convertCell('_int4', '{1,2,3,4}') + * //=> [1,2,3,4] + */ +const convertCell = (type, value) => { + // if data type is an array + if (type.charAt(0) === '_') { + const dataType = type.slice(1, type.length); + return (0, exports.toArray)(value, dataType); + } + // If not null, convert to correct type. + switch (type) { + case PostgresTypes.bool: + return (0, exports.toBoolean)(value); + case PostgresTypes.float4: + case PostgresTypes.float8: + case PostgresTypes.int2: + case PostgresTypes.int4: + case PostgresTypes.int8: + case PostgresTypes.numeric: + case PostgresTypes.oid: + return (0, exports.toNumber)(value); + case PostgresTypes.json: + case PostgresTypes.jsonb: + return (0, exports.toJson)(value); + case PostgresTypes.timestamp: + return (0, exports.toTimestampString)(value); // Format to be consistent with PostgREST + case PostgresTypes.abstime: // To allow users to cast it based on Timezone + case PostgresTypes.date: // To allow users to cast it based on Timezone + case PostgresTypes.daterange: + case PostgresTypes.int4range: + case PostgresTypes.int8range: + case PostgresTypes.money: + case PostgresTypes.reltime: // To allow users to cast it based on Timezone + case PostgresTypes.text: + case PostgresTypes.time: // To allow users to cast it based on Timezone + case PostgresTypes.timestamptz: // To allow users to cast it based on Timezone + case PostgresTypes.timetz: // To allow users to cast it based on Timezone + case PostgresTypes.tsrange: + case PostgresTypes.tstzrange: + return noop(value); + default: + // Return the value for remaining types + return noop(value); + } +}; +exports.convertCell = convertCell; +const noop = (value) => { + return value; +}; +const toBoolean = (value) => { + switch (value) { + case 't': + return true; + case 'f': + return false; + default: + return value; + } +}; +exports.toBoolean = toBoolean; +const toNumber = (value) => { + if (typeof value === 'string') { + const parsedValue = parseFloat(value); + if (!Number.isNaN(parsedValue)) { + return parsedValue; } - this.socket._leaveOpenTopic(this.topic); - this.state = constants_1.CHANNEL_STATES.joining; - this.joinPush.resend(timeout); } - /** @internal */ - _getPayloadRecords(payload) { - const records = { - new: {}, - old: {}, - }; - if (payload.type === 'INSERT' || payload.type === 'UPDATE') { - records.new = Transformers.convertChangeData(payload.columns, payload.record); + return value; +}; +exports.toNumber = toNumber; +const toJson = (value) => { + if (typeof value === 'string') { + try { + return JSON.parse(value); } - if (payload.type === 'UPDATE' || payload.type === 'DELETE') { - records.old = Transformers.convertChangeData(payload.columns, payload.old_record); + catch (_a) { + return value; } - return records; } -} -exports["default"] = RealtimeChannel; -//# sourceMappingURL=RealtimeChannel.js.map + return value; +}; +exports.toJson = toJson; +/** + * Converts a Postgres Array into a native JS array + * + * @example toArray('{}', 'int4') + * //=> [] + * @example toArray('{"[2021-01-01,2021-12-31)","(2021-01-01,2021-12-32]"}', 'daterange') + * //=> ['[2021-01-01,2021-12-31)', '(2021-01-01,2021-12-32]'] + * @example toArray([1,2,3,4], 'int4') + * //=> [1,2,3,4] + */ +const toArray = (value, type) => { + if (typeof value !== 'string') { + return value; + } + const lastIdx = value.length - 1; + const closeBrace = value[lastIdx]; + const openBrace = value[0]; + // Confirm value is a Postgres array by checking curly brackets + if (openBrace === '{' && closeBrace === '}') { + let arr; + const valTrim = value.slice(1, lastIdx); + // TODO: find a better solution to separate Postgres array data + try { + arr = JSON.parse('[' + valTrim + ']'); + } + catch (_) { + // WARNING: splitting on comma does not cover all edge cases + arr = valTrim ? valTrim.split(',') : []; + } + return arr.map((val) => (0, exports.convertCell)(type, val)); + } + return value; +}; +exports.toArray = toArray; +/** + * Fixes timestamp to be ISO-8601. Swaps the space between the date and time for a 'T' + * See https://github.com/supabase/supabase/issues/18 + * + * @example toTimestampString('2019-09-10 00:00:00') + * //=> '2019-09-10T00:00:00' + */ +const toTimestampString = (value) => { + if (typeof value === 'string') { + return value.replace(' ', 'T'); + } + return value; +}; +exports.toTimestampString = toTimestampString; +const httpEndpointURL = (socketUrl) => { + const wsUrl = new URL(socketUrl); + wsUrl.protocol = wsUrl.protocol.replace(/^ws/i, 'http'); + wsUrl.pathname = wsUrl.pathname + .replace(/\/+$/, '') // remove all trailing slashes + .replace(/\/socket\/websocket$/i, '') // remove the socket/websocket path + .replace(/\/socket$/i, '') // remove the socket path + .replace(/\/websocket$/i, ''); // remove the websocket path + if (wsUrl.pathname === '' || wsUrl.pathname === '/') { + wsUrl.pathname = '/api/broadcast'; + } + else { + wsUrl.pathname = wsUrl.pathname + '/api/broadcast'; + } + return wsUrl.href; +}; +exports.httpEndpointURL = httpEndpointURL; +//# sourceMappingURL=transformers.js.map /***/ }), -/***/ 9103: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 318: +/***/ ((__unused_webpack_module, exports) => { "use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -const websocket_1 = __nccwpck_require__(6546); -const constants_1 = __nccwpck_require__(88); -const timer_1 = __importDefault(__nccwpck_require__(2983)); -const serializer_1 = __importDefault(__nccwpck_require__(5360)); -const RealtimeChannel_1 = __importDefault(__nccwpck_require__(9911)); -const noop = () => { }; -class RealtimeClient { +exports.version = void 0; +// Generated automatically during releases by scripts/update-version-files.ts +// This file provides runtime access to the package version for: +// - HTTP request headers (e.g., X-Client-Info header for API requests) +// - Debugging and support (identifying which version is running) +// - Telemetry and logging (version reporting in errors/analytics) +// - Ensuring build artifacts match the published package version +exports.version = '2.99.0'; +//# sourceMappingURL=version.js.map + +/***/ }), + +/***/ 3478: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.WebSocketFactory = void 0; +/** + * Utilities for creating WebSocket instances across runtimes. + */ +class WebSocketFactory { /** - * Initializes the Socket. - * - * @param endPoint The string WebSocket endpoint, ie, "ws://example.com/socket", "wss://example.com", "/socket" (inherited host & protocol) - * @param options.transport The Websocket Transport, for example WebSocket. - * @param options.timeout The default timeout in milliseconds to trigger push timeouts. - * @param options.params The optional params to pass when connecting. - * @param options.headers The optional headers to pass when connecting. - * @param options.heartbeatIntervalMs The millisec interval to send a heartbeat message. - * @param options.logger The optional function for specialized logging, ie: logger: (kind, msg, data) => { console.log(`${kind}: ${msg}`, data) } - * @param options.encode The function to encode outgoing messages. Defaults to JSON: (payload, callback) => callback(JSON.stringify(payload)) - * @param options.decode The function to decode incoming messages. Defaults to Serializer's decode. - * @param options.reconnectAfterMs he optional function that returns the millsec reconnect interval. Defaults to stepped backoff off. + * Static-only utility – prevent instantiation. */ - constructor(endPoint, options) { + constructor() { } + static detectEnvironment() { var _a; - this.accessToken = null; - this.channels = []; - this.endPoint = ''; - this.headers = constants_1.DEFAULT_HEADERS; - this.params = {}; - this.timeout = constants_1.DEFAULT_TIMEOUT; - this.transport = websocket_1.w3cwebsocket; - this.heartbeatIntervalMs = 30000; - this.heartbeatTimer = undefined; - this.pendingHeartbeatRef = null; - this.ref = 0; - this.logger = noop; - this.conn = null; - this.sendBuffer = []; - this.serializer = new serializer_1.default(); - this.stateChangeCallbacks = { - open: [], - close: [], - error: [], - message: [], - }; - /** - * Use either custom fetch, if provided, or default fetch to make HTTP requests - * - * @internal - */ - this._resolveFetch = (customFetch) => { - let _fetch; - if (customFetch) { - _fetch = customFetch; - } - else if (typeof fetch === 'undefined') { - _fetch = (...args) => Promise.resolve().then(() => __importStar(__nccwpck_require__(2668))).then(({ default: fetch }) => fetch(...args)); - } - else { - _fetch = fetch; - } - return (...args) => _fetch(...args); - }; - this.endPoint = `${endPoint}/${constants_1.TRANSPORTS.websocket}`; - if (options === null || options === void 0 ? void 0 : options.params) - this.params = options.params; - if (options === null || options === void 0 ? void 0 : options.headers) - this.headers = Object.assign(Object.assign({}, this.headers), options.headers); - if (options === null || options === void 0 ? void 0 : options.timeout) - this.timeout = options.timeout; - if (options === null || options === void 0 ? void 0 : options.logger) - this.logger = options.logger; - if (options === null || options === void 0 ? void 0 : options.transport) - this.transport = options.transport; - if (options === null || options === void 0 ? void 0 : options.heartbeatIntervalMs) - this.heartbeatIntervalMs = options.heartbeatIntervalMs; - const accessToken = (_a = options === null || options === void 0 ? void 0 : options.params) === null || _a === void 0 ? void 0 : _a.apikey; - if (accessToken) - this.accessToken = accessToken; - this.reconnectAfterMs = (options === null || options === void 0 ? void 0 : options.reconnectAfterMs) - ? options.reconnectAfterMs - : (tries) => { - return [1000, 2000, 5000, 10000][tries - 1] || 10000; + if (typeof WebSocket !== 'undefined') { + return { type: 'native', constructor: WebSocket }; + } + if (typeof globalThis !== 'undefined' && typeof globalThis.WebSocket !== 'undefined') { + return { type: 'native', constructor: globalThis.WebSocket }; + } + if (typeof global !== 'undefined' && typeof global.WebSocket !== 'undefined') { + return { type: 'native', constructor: global.WebSocket }; + } + if (typeof globalThis !== 'undefined' && + typeof globalThis.WebSocketPair !== 'undefined' && + typeof globalThis.WebSocket === 'undefined') { + return { + type: 'cloudflare', + error: 'Cloudflare Workers detected. WebSocket clients are not supported in Cloudflare Workers.', + workaround: 'Use Cloudflare Workers WebSocket API for server-side WebSocket handling, or deploy to a different runtime.', }; - this.encode = (options === null || options === void 0 ? void 0 : options.encode) - ? options.encode - : (payload, callback) => { - return callback(JSON.stringify(payload)); + } + if ((typeof globalThis !== 'undefined' && globalThis.EdgeRuntime) || + (typeof navigator !== 'undefined' && ((_a = navigator.userAgent) === null || _a === void 0 ? void 0 : _a.includes('Vercel-Edge')))) { + return { + type: 'unsupported', + error: 'Edge runtime detected (Vercel Edge/Netlify Edge). WebSockets are not supported in edge functions.', + workaround: 'Use serverless functions or a different deployment target for WebSocket functionality.', }; - this.decode = (options === null || options === void 0 ? void 0 : options.decode) - ? options.decode - : this.serializer.decode.bind(this.serializer); - this.reconnectTimer = new timer_1.default(async () => { - this.disconnect(); - this.connect(); - }, this.reconnectAfterMs); - this.fetch = this._resolveFetch(options === null || options === void 0 ? void 0 : options.fetch); - } - /** - * Connects the socket, unless already connected. - */ - connect() { - if (this.conn) { - return; } - this.conn = new this.transport(this._endPointURL(), [], null, this.headers); - if (this.conn) { - this.conn.binaryType = 'arraybuffer'; - this.conn.onopen = () => this._onConnOpen(); - this.conn.onerror = (error) => this._onConnError(error); - this.conn.onmessage = (event) => this._onConnMessage(event); - this.conn.onclose = (event) => this._onConnClose(event); + // Use dynamic property access to avoid Next.js Edge Runtime static analysis warnings + const _process = globalThis['process']; + if (_process) { + const processVersions = _process['versions']; + if (processVersions && processVersions['node']) { + // Remove 'v' prefix if present and parse the major version + const versionString = processVersions['node']; + const nodeVersion = parseInt(versionString.replace(/^v/, '').split('.')[0]); + // Node.js 22+ should have native WebSocket + if (nodeVersion >= 22) { + // Check if native WebSocket is available (should be in Node.js 22+) + if (typeof globalThis.WebSocket !== 'undefined') { + return { type: 'native', constructor: globalThis.WebSocket }; + } + // If not available, user needs to provide it + return { + type: 'unsupported', + error: `Node.js ${nodeVersion} detected but native WebSocket not found.`, + workaround: 'Provide a WebSocket implementation via the transport option.', + }; + } + // Node.js < 22 doesn't have native WebSocket + return { + type: 'unsupported', + error: `Node.js ${nodeVersion} detected without native WebSocket support.`, + workaround: 'For Node.js < 22, install "ws" package and provide it via the transport option:\n' + + 'import ws from "ws"\n' + + 'new RealtimeClient(url, { transport: ws })', + }; + } } + return { + type: 'unsupported', + error: 'Unknown JavaScript runtime without WebSocket support.', + workaround: "Ensure you're running in a supported environment (browser, Node.js, Deno) or provide a custom WebSocket implementation.", + }; } /** - * Disconnects the socket. + * Returns the best available WebSocket constructor for the current runtime. * - * @param code A numeric status code to send on disconnect. - * @param reason A custom reason for the disconnect. + * @example + * ```ts + * const WS = WebSocketFactory.getWebSocketConstructor() + * const socket = new WS('wss://realtime.supabase.co/socket') + * ``` */ - disconnect(code, reason) { - if (this.conn) { - this.conn.onclose = function () { }; // noop - if (code) { - this.conn.close(code, reason !== null && reason !== void 0 ? reason : ''); - } - else { - this.conn.close(); - } - this.conn = null; - // remove open handles - this.heartbeatTimer && clearInterval(this.heartbeatTimer); - this.reconnectTimer.reset(); + static getWebSocketConstructor() { + const env = this.detectEnvironment(); + if (env.constructor) { + return env.constructor; } - } - /** - * Returns all created channels - */ - getChannels() { - return this.channels; - } - /** - * Unsubscribes and removes a single channel - * @param channel A RealtimeChannel instance - */ - async removeChannel(channel) { - const status = await channel.unsubscribe(); - if (this.channels.length === 0) { - this.disconnect(); + let errorMessage = env.error || 'WebSocket not supported in this environment.'; + if (env.workaround) { + errorMessage += `\n\nSuggested solution: ${env.workaround}`; } - return status; + throw new Error(errorMessage); } /** - * Unsubscribes and removes all channels - */ - async removeAllChannels() { - const values_1 = await Promise.all(this.channels.map((channel) => channel.unsubscribe())); - this.disconnect(); - return values_1; - } - /** - * Logs the message. + * Creates a WebSocket using the detected constructor. * - * For customized logging, `this.logger` can be overridden. + * @example + * ```ts + * const socket = WebSocketFactory.createWebSocket('wss://realtime.supabase.co/socket') + * ``` */ - log(kind, msg, data) { - this.logger(kind, msg, data); + static createWebSocket(url, protocols) { + const WS = this.getWebSocketConstructor(); + return new WS(url, protocols); } /** - * Returns the current state of the socket. + * Detects whether the runtime can establish WebSocket connections. + * + * @example + * ```ts + * if (!WebSocketFactory.isWebSocketSupported()) { + * console.warn('Falling back to long polling') + * } + * ``` */ - connectionState() { - switch (this.conn && this.conn.readyState) { - case constants_1.SOCKET_STATES.connecting: - return constants_1.CONNECTION_STATE.Connecting; - case constants_1.SOCKET_STATES.open: - return constants_1.CONNECTION_STATE.Open; - case constants_1.SOCKET_STATES.closing: - return constants_1.CONNECTION_STATE.Closing; - default: - return constants_1.CONNECTION_STATE.Closed; + static isWebSocketSupported() { + try { + const env = this.detectEnvironment(); + return env.type === 'native' || env.type === 'ws'; + } + catch (_a) { + return false; } - } - /** - * Returns `true` is the connection is open. - */ - isConnected() { - return this.connectionState() === constants_1.CONNECTION_STATE.Open; - } - channel(topic, params = { config: {} }) { - const chan = new RealtimeChannel_1.default(`realtime:${topic}`, params, this); - this.channels.push(chan); - return chan; - } - /** - * Push out a message if the socket is connected. - * - * If the socket is not connected, the message gets enqueued within a local buffer, and sent out when a connection is next established. - */ - push(data) { - const { topic, event, payload, ref } = data; - const callback = () => { - this.encode(data, (result) => { - var _a; - (_a = this.conn) === null || _a === void 0 ? void 0 : _a.send(result); - }); - }; - this.log('push', `${topic} ${event} (${ref})`, payload); - if (this.isConnected()) { - callback(); - } - else { - this.sendBuffer.push(callback); - } - } - /** - * Sets the JWT access token used for channel subscription authorization and Realtime RLS. - * - * @param token A JWT string. - */ - setAuth(token) { - this.accessToken = token; - this.channels.forEach((channel) => { - token && channel.updateJoinPayload({ access_token: token }); - if (channel.joinedOnce && channel._isJoined()) { - channel._push(constants_1.CHANNEL_EVENTS.access_token, { access_token: token }); - } - }); - } - /** - * Return the next message ref, accounting for overflows - * - * @internal - */ - _makeRef() { - let newRef = this.ref + 1; - if (newRef === this.ref) { - this.ref = 0; - } - else { - this.ref = newRef; - } - return this.ref.toString(); - } - /** - * Unsubscribe from channels with the specified topic. - * - * @internal - */ - _leaveOpenTopic(topic) { - let dupChannel = this.channels.find((c) => c.topic === topic && (c._isJoined() || c._isJoining())); - if (dupChannel) { - this.log('transport', `leaving duplicate topic "${topic}"`); - dupChannel.unsubscribe(); - } - } - /** - * Removes a subscription from the socket. - * - * @param channel An open subscription. - * - * @internal - */ - _remove(channel) { - this.channels = this.channels.filter((c) => c._joinRef() !== channel._joinRef()); - } - /** - * Returns the URL of the websocket. - * - * @internal - */ - _endPointURL() { - return this._appendParams(this.endPoint, Object.assign({}, this.params, { vsn: constants_1.VSN })); - } - /** @internal */ - _onConnMessage(rawMessage) { - this.decode(rawMessage.data, (msg) => { - let { topic, event, payload, ref } = msg; - if ((ref && ref === this.pendingHeartbeatRef) || - event === (payload === null || payload === void 0 ? void 0 : payload.type)) { - this.pendingHeartbeatRef = null; - } - this.log('receive', `${payload.status || ''} ${topic} ${event} ${(ref && '(' + ref + ')') || ''}`, payload); - this.channels - .filter((channel) => channel._isMember(topic)) - .forEach((channel) => channel._trigger(event, payload, ref)); - this.stateChangeCallbacks.message.forEach((callback) => callback(msg)); - }); - } - /** @internal */ - _onConnOpen() { - this.log('transport', `connected to ${this._endPointURL()}`); - this._flushSendBuffer(); - this.reconnectTimer.reset(); - this.heartbeatTimer && clearInterval(this.heartbeatTimer); - this.heartbeatTimer = setInterval(() => this._sendHeartbeat(), this.heartbeatIntervalMs); - this.stateChangeCallbacks.open.forEach((callback) => callback()); - } - /** @internal */ - _onConnClose(event) { - this.log('transport', 'close', event); - this._triggerChanError(); - this.heartbeatTimer && clearInterval(this.heartbeatTimer); - this.reconnectTimer.scheduleTimeout(); - this.stateChangeCallbacks.close.forEach((callback) => callback(event)); - } - /** @internal */ - _onConnError(error) { - this.log('transport', error.message); - this._triggerChanError(); - this.stateChangeCallbacks.error.forEach((callback) => callback(error)); - } - /** @internal */ - _triggerChanError() { - this.channels.forEach((channel) => channel._trigger(constants_1.CHANNEL_EVENTS.error)); - } - /** @internal */ - _appendParams(url, params) { - if (Object.keys(params).length === 0) { - return url; - } - const prefix = url.match(/\?/) ? '&' : '?'; - const query = new URLSearchParams(params); - return `${url}${prefix}${query}`; - } - /** @internal */ - _flushSendBuffer() { - if (this.isConnected() && this.sendBuffer.length > 0) { - this.sendBuffer.forEach((callback) => callback()); - this.sendBuffer = []; - } - } - /** @internal */ - _sendHeartbeat() { - var _a; - if (!this.isConnected()) { - return; - } - if (this.pendingHeartbeatRef) { - this.pendingHeartbeatRef = null; - this.log('transport', 'heartbeat timeout. Attempting to re-establish connection'); - (_a = this.conn) === null || _a === void 0 ? void 0 : _a.close(constants_1.WS_CLOSE_NORMAL, 'hearbeat timeout'); - return; - } - this.pendingHeartbeatRef = this._makeRef(); - this.push({ - topic: 'phoenix', - event: 'heartbeat', - payload: {}, - ref: this.pendingHeartbeatRef, - }); - this.setAuth(this.accessToken); } } -exports["default"] = RealtimeClient; -//# sourceMappingURL=RealtimeClient.js.map +exports.WebSocketFactory = WebSocketFactory; +exports["default"] = WebSocketFactory; +//# sourceMappingURL=websocket-factory.js.map /***/ }), -/***/ 5583: -/***/ ((__unused_webpack_module, exports) => { +/***/ 7647: +/***/ ((module) => { -"use strict"; +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +/* global global, define, Symbol, Reflect, Promise, SuppressedError, Iterator */ +var __extends; +var __assign; +var __rest; +var __decorate; +var __param; +var __esDecorate; +var __runInitializers; +var __propKey; +var __setFunctionName; +var __metadata; +var __awaiter; +var __generator; +var __exportStar; +var __values; +var __read; +var __spread; +var __spreadArrays; +var __spreadArray; +var __await; +var __asyncGenerator; +var __asyncDelegator; +var __asyncValues; +var __makeTemplateObject; +var __importStar; +var __importDefault; +var __classPrivateFieldGet; +var __classPrivateFieldSet; +var __classPrivateFieldIn; +var __createBinding; +var __addDisposableResource; +var __disposeResources; +var __rewriteRelativeImportExtension; +(function (factory) { + var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {}; + if (typeof define === "function" && define.amd) { + define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); }); + } + else if ( true && typeof module.exports === "object") { + factory(createExporter(root, createExporter(module.exports))); + } + else { + factory(createExporter(root)); + } + function createExporter(exports, previous) { + if (exports !== root) { + if (typeof Object.create === "function") { + Object.defineProperty(exports, "__esModule", { value: true }); + } + else { + exports.__esModule = true; + } + } + return function (id, v) { return exports[id] = previous ? previous(id, v) : v; }; + } +}) +(function (exporter) { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + + __extends = function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; + + __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; + }; + + __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; + }; + + __decorate = function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + 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; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + + __param = function (paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } + }; + + __esDecorate = function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { + function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } + var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; + var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; + var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); + var _, done = false; + for (var i = decorators.length - 1; i >= 0; i--) { + var context = {}; + for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; + for (var p in contextIn.access) context.access[p] = contextIn.access[p]; + context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; + var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); + if (kind === "accessor") { + if (result === void 0) continue; + if (result === null || typeof result !== "object") throw new TypeError("Object expected"); + if (_ = accept(result.get)) descriptor.get = _; + if (_ = accept(result.set)) descriptor.set = _; + if (_ = accept(result.init)) initializers.unshift(_); + } + else if (_ = accept(result)) { + if (kind === "field") initializers.unshift(_); + else descriptor[key] = _; + } + } + if (target) Object.defineProperty(target, contextIn.name, descriptor); + done = true; + }; + + __runInitializers = function (thisArg, initializers, value) { + var useValue = arguments.length > 2; + for (var i = 0; i < initializers.length; i++) { + value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); + } + return useValue ? value : void 0; + }; + + __propKey = function (x) { + return typeof x === "symbol" ? x : "".concat(x); + }; + + __setFunctionName = function (f, name, prefix) { + if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; + return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); + }; + + __metadata = function (metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); + }; + + __awaiter = function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + + __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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); + return g.next = verb(0), g["throw"] = verb(1), g["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 (g && (g = 0, op[0] && (_ = 0)), _) 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 }; + } + }; + + __exportStar = function(m, o) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); + }; + + __createBinding = Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + }); + + __values = function (o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + }; + + __read = function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; + }; + + /** @deprecated */ + __spread = function () { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; + }; + + /** @deprecated */ + __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; + }; + + __spreadArray = function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); + }; + + __await = function (v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); + }; + + __asyncGenerator = function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; + function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } + function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } + }; + + __asyncDelegator = function (o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; + function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } + }; + + __asyncValues = function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + 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); + 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); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } + }; + + __makeTemplateObject = function (cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; + }; + + var __setModuleDefault = Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + }) : function(o, v) { + o["default"] = v; + }; + + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + + __importStar = function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; + + __importDefault = function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + + __classPrivateFieldGet = function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); + }; + + __classPrivateFieldSet = function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; + }; + + __classPrivateFieldIn = function (state, receiver) { + if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); + return typeof state === "function" ? receiver === state : state.has(receiver); + }; + + __addDisposableResource = function (env, value, async) { + if (value !== null && value !== void 0) { + if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); + var dispose, inner; + if (async) { + if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); + dispose = value[Symbol.asyncDispose]; + } + if (dispose === void 0) { + if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); + dispose = value[Symbol.dispose]; + if (async) inner = dispose; + } + if (typeof dispose !== "function") throw new TypeError("Object not disposable."); + if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } }; + env.stack.push({ value: value, dispose: dispose, async: async }); + } + else if (async) { + env.stack.push({ async: true }); + } + return value; + }; + + var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; + }; + + __disposeResources = function (env) { + function fail(e) { + env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; + env.hasError = true; + } + var r, s = 0; + function next() { + while (r = env.stack.pop()) { + try { + if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); + if (r.dispose) { + var result = r.dispose.call(r.value); + if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); + } + else s |= 1; + } + catch (e) { + fail(e); + } + } + if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); + if (env.hasError) throw env.error; + } + return next(); + }; + + __rewriteRelativeImportExtension = function (path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); + } + return path; + }; + + exporter("__extends", __extends); + exporter("__assign", __assign); + exporter("__rest", __rest); + exporter("__decorate", __decorate); + exporter("__param", __param); + exporter("__esDecorate", __esDecorate); + exporter("__runInitializers", __runInitializers); + exporter("__propKey", __propKey); + exporter("__setFunctionName", __setFunctionName); + exporter("__metadata", __metadata); + exporter("__awaiter", __awaiter); + exporter("__generator", __generator); + exporter("__exportStar", __exportStar); + exporter("__createBinding", __createBinding); + exporter("__values", __values); + exporter("__read", __read); + exporter("__spread", __spread); + exporter("__spreadArrays", __spreadArrays); + exporter("__spreadArray", __spreadArray); + exporter("__await", __await); + exporter("__asyncGenerator", __asyncGenerator); + exporter("__asyncDelegator", __asyncDelegator); + exporter("__asyncValues", __asyncValues); + exporter("__makeTemplateObject", __makeTemplateObject); + exporter("__importStar", __importStar); + exporter("__importDefault", __importDefault); + exporter("__classPrivateFieldGet", __classPrivateFieldGet); + exporter("__classPrivateFieldSet", __classPrivateFieldSet); + exporter("__classPrivateFieldIn", __classPrivateFieldIn); + exporter("__addDisposableResource", __addDisposableResource); + exporter("__disposeResources", __disposeResources); + exporter("__rewriteRelativeImportExtension", __rewriteRelativeImportExtension); +}); + +0 && (0); -/* - This file draws heavily from https://github.com/phoenixframework/phoenix/blob/d344ec0a732ab4ee204215b31de69cf4be72e3bf/assets/js/phoenix/presence.js - License: https://github.com/phoenixframework/phoenix/blob/d344ec0a732ab4ee204215b31de69cf4be72e3bf/LICENSE.md -*/ -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.REALTIME_PRESENCE_LISTEN_EVENTS = void 0; -var REALTIME_PRESENCE_LISTEN_EVENTS; -(function (REALTIME_PRESENCE_LISTEN_EVENTS) { - REALTIME_PRESENCE_LISTEN_EVENTS["SYNC"] = "sync"; - REALTIME_PRESENCE_LISTEN_EVENTS["JOIN"] = "join"; - REALTIME_PRESENCE_LISTEN_EVENTS["LEAVE"] = "leave"; -})(REALTIME_PRESENCE_LISTEN_EVENTS = exports.REALTIME_PRESENCE_LISTEN_EVENTS || (exports.REALTIME_PRESENCE_LISTEN_EVENTS = {})); -class RealtimePresence { - /** - * Initializes the Presence. - * - * @param channel - The RealtimeChannel - * @param opts - The options, - * for example `{events: {state: 'state', diff: 'diff'}}` - */ - constructor(channel, opts) { - this.channel = channel; - this.state = {}; - this.pendingDiffs = []; - this.joinRef = null; - this.caller = { - onJoin: () => { }, - onLeave: () => { }, - onSync: () => { }, - }; - const events = (opts === null || opts === void 0 ? void 0 : opts.events) || { - state: 'presence_state', - diff: 'presence_diff', - }; - this.channel._on(events.state, {}, (newState) => { - const { onJoin, onLeave, onSync } = this.caller; - this.joinRef = this.channel._joinRef(); - this.state = RealtimePresence.syncState(this.state, newState, onJoin, onLeave); - this.pendingDiffs.forEach((diff) => { - this.state = RealtimePresence.syncDiff(this.state, diff, onJoin, onLeave); - }); - this.pendingDiffs = []; - onSync(); - }); - this.channel._on(events.diff, {}, (diff) => { - const { onJoin, onLeave, onSync } = this.caller; - if (this.inPendingSyncState()) { - this.pendingDiffs.push(diff); - } - else { - this.state = RealtimePresence.syncDiff(this.state, diff, onJoin, onLeave); - onSync(); - } - }); - this.onJoin((key, currentPresences, newPresences) => { - this.channel._trigger('presence', { - event: 'join', - key, - currentPresences, - newPresences, - }); - }); - this.onLeave((key, currentPresences, leftPresences) => { - this.channel._trigger('presence', { - event: 'leave', - key, - currentPresences, - leftPresences, - }); - }); - this.onSync(() => { - this.channel._trigger('presence', { event: 'sync' }); - }); - } - /** - * Used to sync the list of presences on the server with the - * client's state. - * - * An optional `onJoin` and `onLeave` callback can be provided to - * react to changes in the client's local presences across - * disconnects and reconnects with the server. - * - * @internal - */ - static syncState(currentState, newState, onJoin, onLeave) { - const state = this.cloneDeep(currentState); - const transformedState = this.transformState(newState); - const joins = {}; - const leaves = {}; - this.map(state, (key, presences) => { - if (!transformedState[key]) { - leaves[key] = presences; - } - }); - this.map(transformedState, (key, newPresences) => { - const currentPresences = state[key]; - if (currentPresences) { - const newPresenceRefs = newPresences.map((m) => m.presence_ref); - const curPresenceRefs = currentPresences.map((m) => m.presence_ref); - const joinedPresences = newPresences.filter((m) => curPresenceRefs.indexOf(m.presence_ref) < 0); - const leftPresences = currentPresences.filter((m) => newPresenceRefs.indexOf(m.presence_ref) < 0); - if (joinedPresences.length > 0) { - joins[key] = joinedPresences; - } - if (leftPresences.length > 0) { - leaves[key] = leftPresences; - } - } - else { - joins[key] = newPresences; - } - }); - return this.syncDiff(state, { joins, leaves }, onJoin, onLeave); - } - /** - * Used to sync a diff of presence join and leave events from the - * server, as they happen. - * - * Like `syncState`, `syncDiff` accepts optional `onJoin` and - * `onLeave` callbacks to react to a user joining or leaving from a - * device. - * - * @internal - */ - static syncDiff(state, diff, onJoin, onLeave) { - const { joins, leaves } = { - joins: this.transformState(diff.joins), - leaves: this.transformState(diff.leaves), - }; - if (!onJoin) { - onJoin = () => { }; - } - if (!onLeave) { - onLeave = () => { }; - } - this.map(joins, (key, newPresences) => { - var _a; - const currentPresences = (_a = state[key]) !== null && _a !== void 0 ? _a : []; - state[key] = this.cloneDeep(newPresences); - if (currentPresences.length > 0) { - const joinedPresenceRefs = state[key].map((m) => m.presence_ref); - const curPresences = currentPresences.filter((m) => joinedPresenceRefs.indexOf(m.presence_ref) < 0); - state[key].unshift(...curPresences); - } - onJoin(key, currentPresences, newPresences); - }); - this.map(leaves, (key, leftPresences) => { - let currentPresences = state[key]; - if (!currentPresences) - return; - const presenceRefsToRemove = leftPresences.map((m) => m.presence_ref); - currentPresences = currentPresences.filter((m) => presenceRefsToRemove.indexOf(m.presence_ref) < 0); - state[key] = currentPresences; - onLeave(key, currentPresences, leftPresences); - if (currentPresences.length === 0) - delete state[key]; - }); - return state; - } - /** @internal */ - static map(obj, func) { - return Object.getOwnPropertyNames(obj).map((key) => func(key, obj[key])); - } - /** - * Remove 'metas' key - * Change 'phx_ref' to 'presence_ref' - * Remove 'phx_ref' and 'phx_ref_prev' - * - * @example - * // returns { - * abc123: [ - * { presence_ref: '2', user_id: 1 }, - * { presence_ref: '3', user_id: 2 } - * ] - * } - * RealtimePresence.transformState({ - * abc123: { - * metas: [ - * { phx_ref: '2', phx_ref_prev: '1' user_id: 1 }, - * { phx_ref: '3', user_id: 2 } - * ] - * } - * }) - * - * @internal - */ - static transformState(state) { - state = this.cloneDeep(state); - return Object.getOwnPropertyNames(state).reduce((newState, key) => { - const presences = state[key]; - if ('metas' in presences) { - newState[key] = presences.metas.map((presence) => { - presence['presence_ref'] = presence['phx_ref']; - delete presence['phx_ref']; - delete presence['phx_ref_prev']; - return presence; - }); - } - else { - newState[key] = presences; - } - return newState; - }, {}); - } - /** @internal */ - static cloneDeep(obj) { - return JSON.parse(JSON.stringify(obj)); - } - /** @internal */ - onJoin(callback) { - this.caller.onJoin = callback; - } - /** @internal */ - onLeave(callback) { - this.caller.onLeave = callback; - } - /** @internal */ - onSync(callback) { - this.caller.onSync = callback; - } - /** @internal */ - inPendingSyncState() { - return !this.joinRef || this.joinRef !== this.channel._joinRef(); - } -} -exports["default"] = RealtimePresence; -//# sourceMappingURL=RealtimePresence.js.map /***/ }), -/***/ 442: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 4243: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.REALTIME_CHANNEL_STATES = exports.REALTIME_SUBSCRIBE_STATES = exports.REALTIME_PRESENCE_LISTEN_EVENTS = exports.REALTIME_POSTGRES_CHANGES_LISTEN_EVENT = exports.REALTIME_LISTEN_TYPES = exports.RealtimeClient = exports.RealtimeChannel = exports.RealtimePresence = void 0; -const RealtimeClient_1 = __importDefault(__nccwpck_require__(9103)); -exports.RealtimeClient = RealtimeClient_1.default; -const RealtimeChannel_1 = __importStar(__nccwpck_require__(9911)); -exports.RealtimeChannel = RealtimeChannel_1.default; -Object.defineProperty(exports, "REALTIME_LISTEN_TYPES", ({ enumerable: true, get: function () { return RealtimeChannel_1.REALTIME_LISTEN_TYPES; } })); -Object.defineProperty(exports, "REALTIME_POSTGRES_CHANGES_LISTEN_EVENT", ({ enumerable: true, get: function () { return RealtimeChannel_1.REALTIME_POSTGRES_CHANGES_LISTEN_EVENT; } })); -Object.defineProperty(exports, "REALTIME_SUBSCRIBE_STATES", ({ enumerable: true, get: function () { return RealtimeChannel_1.REALTIME_SUBSCRIBE_STATES; } })); -Object.defineProperty(exports, "REALTIME_CHANNEL_STATES", ({ enumerable: true, get: function () { return RealtimeChannel_1.REALTIME_CHANNEL_STATES; } })); -const RealtimePresence_1 = __importStar(__nccwpck_require__(5583)); -exports.RealtimePresence = RealtimePresence_1.default; -Object.defineProperty(exports, "REALTIME_PRESENCE_LISTEN_EVENTS", ({ enumerable: true, get: function () { return RealtimePresence_1.REALTIME_PRESENCE_LISTEN_EVENTS; } })); -//# sourceMappingURL=index.js.map -/***/ }), +const XHTMLEntities = __nccwpck_require__(3096); -/***/ 88: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +const hexNumber = /^[\da-fA-F]+$/; +const decimalNumber = /^\d+$/; -"use strict"; +// The map to `acorn-jsx` tokens from `acorn` namespace objects. +const acornJsxMap = new WeakMap(); -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.CONNECTION_STATE = exports.TRANSPORTS = exports.CHANNEL_EVENTS = exports.CHANNEL_STATES = exports.SOCKET_STATES = exports.WS_CLOSE_NORMAL = exports.DEFAULT_TIMEOUT = exports.VSN = exports.DEFAULT_HEADERS = void 0; -const version_1 = __nccwpck_require__(318); -exports.DEFAULT_HEADERS = { 'X-Client-Info': `realtime-js/${version_1.version}` }; -exports.VSN = '1.0.0'; -exports.DEFAULT_TIMEOUT = 10000; -exports.WS_CLOSE_NORMAL = 1000; -var SOCKET_STATES; -(function (SOCKET_STATES) { - SOCKET_STATES[SOCKET_STATES["connecting"] = 0] = "connecting"; - SOCKET_STATES[SOCKET_STATES["open"] = 1] = "open"; - SOCKET_STATES[SOCKET_STATES["closing"] = 2] = "closing"; - SOCKET_STATES[SOCKET_STATES["closed"] = 3] = "closed"; -})(SOCKET_STATES = exports.SOCKET_STATES || (exports.SOCKET_STATES = {})); -var CHANNEL_STATES; -(function (CHANNEL_STATES) { - CHANNEL_STATES["closed"] = "closed"; - CHANNEL_STATES["errored"] = "errored"; - CHANNEL_STATES["joined"] = "joined"; - CHANNEL_STATES["joining"] = "joining"; - CHANNEL_STATES["leaving"] = "leaving"; -})(CHANNEL_STATES = exports.CHANNEL_STATES || (exports.CHANNEL_STATES = {})); -var CHANNEL_EVENTS; -(function (CHANNEL_EVENTS) { - CHANNEL_EVENTS["close"] = "phx_close"; - CHANNEL_EVENTS["error"] = "phx_error"; - CHANNEL_EVENTS["join"] = "phx_join"; - CHANNEL_EVENTS["reply"] = "phx_reply"; - CHANNEL_EVENTS["leave"] = "phx_leave"; - CHANNEL_EVENTS["access_token"] = "access_token"; -})(CHANNEL_EVENTS = exports.CHANNEL_EVENTS || (exports.CHANNEL_EVENTS = {})); -var TRANSPORTS; -(function (TRANSPORTS) { - TRANSPORTS["websocket"] = "websocket"; -})(TRANSPORTS = exports.TRANSPORTS || (exports.TRANSPORTS = {})); -var CONNECTION_STATE; -(function (CONNECTION_STATE) { - CONNECTION_STATE["Connecting"] = "connecting"; - CONNECTION_STATE["Open"] = "open"; - CONNECTION_STATE["Closing"] = "closing"; - CONNECTION_STATE["Closed"] = "closed"; -})(CONNECTION_STATE = exports.CONNECTION_STATE || (exports.CONNECTION_STATE = {})); -//# sourceMappingURL=constants.js.map +// Get the original tokens for the given `acorn` namespace object. +function getJsxTokens(acorn) { + acorn = acorn.Parser.acorn || acorn; + let acornJsx = acornJsxMap.get(acorn); + if (!acornJsx) { + const tt = acorn.tokTypes; + const TokContext = acorn.TokContext; + const TokenType = acorn.TokenType; + const tc_oTag = new TokContext('...', true, true); + const tokContexts = { + tc_oTag: tc_oTag, + tc_cTag: tc_cTag, + tc_expr: tc_expr + }; + const tokTypes = { + jsxName: new TokenType('jsxName'), + jsxText: new TokenType('jsxText', {beforeExpr: true}), + jsxTagStart: new TokenType('jsxTagStart', {startsExpr: true}), + jsxTagEnd: new TokenType('jsxTagEnd') + }; -/***/ }), + tokTypes.jsxTagStart.updateContext = function() { + this.context.push(tc_expr); // treat as beginning of JSX expression + this.context.push(tc_oTag); // start opening tag context + this.exprAllowed = false; + }; + tokTypes.jsxTagEnd.updateContext = function(prevType) { + let out = this.context.pop(); + if (out === tc_oTag && prevType === tt.slash || out === tc_cTag) { + this.context.pop(); + this.exprAllowed = this.curContext() === tc_expr; + } else { + this.exprAllowed = true; + } + }; -/***/ 2292: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + acornJsx = { tokContexts: tokContexts, tokTypes: tokTypes }; + acornJsxMap.set(acorn, acornJsx); + } -"use strict"; + return acornJsx; +} -Object.defineProperty(exports, "__esModule", ({ value: true })); -const constants_1 = __nccwpck_require__(88); -class Push { - /** - * Initializes the Push - * - * @param channel The Channel - * @param event The event, for example `"phx_join"` - * @param payload The payload, for example `{user_id: 123}` - * @param timeout The push timeout in milliseconds - */ - constructor(channel, event, payload = {}, timeout = constants_1.DEFAULT_TIMEOUT) { - this.channel = channel; - this.event = event; - this.payload = payload; - this.timeout = timeout; - this.sent = false; - this.timeoutTimer = undefined; - this.ref = ''; - this.receivedResp = null; - this.recHooks = []; - this.refEvent = null; - } - resend(timeout) { - this.timeout = timeout; - this._cancelRefEvent(); - this.ref = ''; - this.refEvent = null; - this.receivedResp = null; - this.sent = false; - this.send(); +// Transforms JSX element name to string. + +function getQualifiedJSXName(object) { + if (!object) + return object; + + if (object.type === 'JSXIdentifier') + return object.name; + + if (object.type === 'JSXNamespacedName') + return object.namespace.name + ':' + object.name.name; + + if (object.type === 'JSXMemberExpression') + return getQualifiedJSXName(object.object) + '.' + + getQualifiedJSXName(object.property); +} + +module.exports = function(options) { + options = options || {}; + return function(Parser) { + return plugin({ + allowNamespaces: options.allowNamespaces !== false, + allowNamespacedObjects: !!options.allowNamespacedObjects + }, Parser); + }; +}; + +// This is `tokTypes` of the peer dep. +// This can be different instances from the actual `tokTypes` this plugin uses. +Object.defineProperty(module.exports, "tokTypes", ({ + get: function get_tokTypes() { + return getJsxTokens(__nccwpck_require__(390)).tokTypes; + }, + configurable: true, + enumerable: true +})); + +function plugin(options, Parser) { + const acorn = Parser.acorn || __nccwpck_require__(390); + const acornJsx = getJsxTokens(acorn); + const tt = acorn.tokTypes; + const tok = acornJsx.tokTypes; + const tokContexts = acorn.tokContexts; + const tc_oTag = acornJsx.tokContexts.tc_oTag; + const tc_cTag = acornJsx.tokContexts.tc_cTag; + const tc_expr = acornJsx.tokContexts.tc_expr; + const isNewLine = acorn.isNewLine; + const isIdentifierStart = acorn.isIdentifierStart; + const isIdentifierChar = acorn.isIdentifierChar; + + return class extends Parser { + // Expose actual `tokTypes` and `tokContexts` to other plugins. + static get acornJsx() { + return acornJsx; } - send() { - if (this._hasReceived('timeout')) { - return; + + // Reads inline JSX contents token. + jsx_readToken() { + let out = '', chunkStart = this.pos; + for (;;) { + if (this.pos >= this.input.length) + this.raise(this.start, 'Unterminated JSX contents'); + let ch = this.input.charCodeAt(this.pos); + + switch (ch) { + case 60: // '<' + case 123: // '{' + if (this.pos === this.start) { + if (ch === 60 && this.exprAllowed) { + ++this.pos; + return this.finishToken(tok.jsxTagStart); + } + return this.getTokenFromCode(ch); + } + out += this.input.slice(chunkStart, this.pos); + return this.finishToken(tok.jsxText, out); + + case 38: // '&' + out += this.input.slice(chunkStart, this.pos); + out += this.jsx_readEntity(); + chunkStart = this.pos; + break; + + case 62: // '>' + case 125: // '}' + this.raise( + this.pos, + "Unexpected token `" + this.input[this.pos] + "`. Did you mean `" + + (ch === 62 ? ">" : "}") + "` or " + "`{\"" + this.input[this.pos] + "\"}" + "`?" + ); + + default: + if (isNewLine(ch)) { + out += this.input.slice(chunkStart, this.pos); + out += this.jsx_readNewLine(true); + chunkStart = this.pos; + } else { + ++this.pos; + } } - this.startTimeout(); - this.sent = true; - this.channel.socket.push({ - topic: this.channel.topic, - event: this.event, - payload: this.payload, - ref: this.ref, - join_ref: this.channel._joinRef(), - }); + } } - updatePayload(payload) { - this.payload = Object.assign(Object.assign({}, this.payload), payload); + + jsx_readNewLine(normalizeCRLF) { + let ch = this.input.charCodeAt(this.pos); + let out; + ++this.pos; + if (ch === 13 && this.input.charCodeAt(this.pos) === 10) { + ++this.pos; + out = normalizeCRLF ? '\n' : '\r\n'; + } else { + out = String.fromCharCode(ch); + } + if (this.options.locations) { + ++this.curLine; + this.lineStart = this.pos; + } + + return out; } - receive(status, callback) { - var _a; - if (this._hasReceived(status)) { - callback((_a = this.receivedResp) === null || _a === void 0 ? void 0 : _a.response); + + jsx_readString(quote) { + let out = '', chunkStart = ++this.pos; + for (;;) { + if (this.pos >= this.input.length) + this.raise(this.start, 'Unterminated string constant'); + let ch = this.input.charCodeAt(this.pos); + if (ch === quote) break; + if (ch === 38) { // '&' + out += this.input.slice(chunkStart, this.pos); + out += this.jsx_readEntity(); + chunkStart = this.pos; + } else if (isNewLine(ch)) { + out += this.input.slice(chunkStart, this.pos); + out += this.jsx_readNewLine(false); + chunkStart = this.pos; + } else { + ++this.pos; } - this.recHooks.push({ status, callback }); - return this; + } + out += this.input.slice(chunkStart, this.pos++); + return this.finishToken(tt.string, out); } - startTimeout() { - if (this.timeoutTimer) { - return; + + jsx_readEntity() { + let str = '', count = 0, entity; + let ch = this.input[this.pos]; + if (ch !== '&') + this.raise(this.pos, 'Entity must start with an ampersand'); + let startPos = ++this.pos; + while (this.pos < this.input.length && count++ < 10) { + ch = this.input[this.pos++]; + if (ch === ';') { + if (str[0] === '#') { + if (str[1] === 'x') { + str = str.substr(2); + if (hexNumber.test(str)) + entity = String.fromCharCode(parseInt(str, 16)); + } else { + str = str.substr(1); + if (decimalNumber.test(str)) + entity = String.fromCharCode(parseInt(str, 10)); + } + } else { + entity = XHTMLEntities[str]; + } + break; } - this.ref = this.channel.socket._makeRef(); - this.refEvent = this.channel._replyEventName(this.ref); - const callback = (payload) => { - this._cancelRefEvent(); - this._cancelTimeout(); - this.receivedResp = payload; - this._matchReceive(payload); - }; - this.channel._on(this.refEvent, {}, callback); - this.timeoutTimer = setTimeout(() => { - this.trigger('timeout', {}); - }, this.timeout); - } - trigger(status, response) { - if (this.refEvent) - this.channel._trigger(this.refEvent, { status, response }); - } - destroy() { - this._cancelRefEvent(); - this._cancelTimeout(); + str += ch; + } + if (!entity) { + this.pos = startPos; + return '&'; + } + return entity; } - _cancelRefEvent() { - if (!this.refEvent) { - return; - } - this.channel._off(this.refEvent, {}); + + // Read a JSX identifier (valid tag or attribute name). + // + // Optimized version since JSX identifiers can't contain + // escape characters and so can be read as single slice. + // Also assumes that first character was already checked + // by isIdentifierStart in readToken. + + jsx_readWord() { + let ch, start = this.pos; + do { + ch = this.input.charCodeAt(++this.pos); + } while (isIdentifierChar(ch) || ch === 45); // '-' + return this.finishToken(tok.jsxName, this.input.slice(start, this.pos)); } - _cancelTimeout() { - clearTimeout(this.timeoutTimer); - this.timeoutTimer = undefined; + + // Parse next token as JSX identifier + + jsx_parseIdentifier() { + let node = this.startNode(); + if (this.type === tok.jsxName) + node.name = this.value; + else if (this.type.keyword) + node.name = this.type.keyword; + else + this.unexpected(); + this.next(); + return this.finishNode(node, 'JSXIdentifier'); } - _matchReceive({ status, response, }) { - this.recHooks - .filter((h) => h.status === status) - .forEach((h) => h.callback(response)); + + // Parse namespaced identifier. + + jsx_parseNamespacedName() { + let startPos = this.start, startLoc = this.startLoc; + let name = this.jsx_parseIdentifier(); + if (!options.allowNamespaces || !this.eat(tt.colon)) return name; + var node = this.startNodeAt(startPos, startLoc); + node.namespace = name; + node.name = this.jsx_parseIdentifier(); + return this.finishNode(node, 'JSXNamespacedName'); } - _hasReceived(status) { - return this.receivedResp && this.receivedResp.status === status; + + // Parses element name in any form - namespaced, member + // or single identifier. + + jsx_parseElementName() { + if (this.type === tok.jsxTagEnd) return ''; + let startPos = this.start, startLoc = this.startLoc; + let node = this.jsx_parseNamespacedName(); + if (this.type === tt.dot && node.type === 'JSXNamespacedName' && !options.allowNamespacedObjects) { + this.unexpected(); + } + while (this.eat(tt.dot)) { + let newNode = this.startNodeAt(startPos, startLoc); + newNode.object = node; + newNode.property = this.jsx_parseIdentifier(); + node = this.finishNode(newNode, 'JSXMemberExpression'); + } + return node; } -} -exports["default"] = Push; -//# sourceMappingURL=push.js.map -/***/ }), + // Parses any type of JSX attribute value. -/***/ 5360: -/***/ ((__unused_webpack_module, exports) => { + jsx_parseAttributeValue() { + switch (this.type) { + case tt.braceL: + let node = this.jsx_parseExpressionContainer(); + if (node.expression.type === 'JSXEmptyExpression') + this.raise(node.start, 'JSX attributes must only be assigned a non-empty expression'); + return node; -"use strict"; + case tok.jsxTagStart: + case tt.string: + return this.parseExprAtom(); -// This file draws heavily from https://github.com/phoenixframework/phoenix/commit/cf098e9cf7a44ee6479d31d911a97d3c7430c6fe -// License: https://github.com/phoenixframework/phoenix/blob/master/LICENSE.md -Object.defineProperty(exports, "__esModule", ({ value: true })); -class Serializer { - constructor() { - this.HEADER_LENGTH = 1; - } - decode(rawPayload, callback) { - if (rawPayload.constructor === ArrayBuffer) { - return callback(this._binaryDecode(rawPayload)); - } - if (typeof rawPayload === 'string') { - return callback(JSON.parse(rawPayload)); - } - return callback({}); - } - _binaryDecode(buffer) { - const view = new DataView(buffer); - const decoder = new TextDecoder(); - return this._decodeBroadcast(buffer, view, decoder); + default: + this.raise(this.start, 'JSX value should be either an expression or a quoted JSX text'); + } } - _decodeBroadcast(buffer, view, decoder) { - const topicSize = view.getUint8(1); - const eventSize = view.getUint8(2); - let offset = this.HEADER_LENGTH + 2; - const topic = decoder.decode(buffer.slice(offset, offset + topicSize)); - offset = offset + topicSize; - const event = decoder.decode(buffer.slice(offset, offset + eventSize)); - offset = offset + eventSize; - const data = JSON.parse(decoder.decode(buffer.slice(offset, buffer.byteLength))); - return { ref: null, topic: topic, event: event, payload: data }; + + // JSXEmptyExpression is unique type since it doesn't actually parse anything, + // and so it should start at the end of last read token (left brace) and finish + // at the beginning of the next one (right brace). + + jsx_parseEmptyExpression() { + let node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc); + return this.finishNodeAt(node, 'JSXEmptyExpression', this.start, this.startLoc); } -} -exports["default"] = Serializer; -//# sourceMappingURL=serializer.js.map -/***/ }), + // Parses JSX expression enclosed into curly brackets. -/***/ 2983: -/***/ ((__unused_webpack_module, exports) => { + jsx_parseExpressionContainer() { + let node = this.startNode(); + this.next(); + node.expression = this.type === tt.braceR + ? this.jsx_parseEmptyExpression() + : this.parseExpression(); + this.expect(tt.braceR); + return this.finishNode(node, 'JSXExpressionContainer'); + } -"use strict"; + // Parses following JSX attribute name-value pair. -Object.defineProperty(exports, "__esModule", ({ value: true })); -/** - * Creates a timer that accepts a `timerCalc` function to perform calculated timeout retries, such as exponential backoff. - * - * @example - * let reconnectTimer = new Timer(() => this.connect(), function(tries){ - * return [1000, 5000, 10000][tries - 1] || 10000 - * }) - * reconnectTimer.scheduleTimeout() // fires after 1000 - * reconnectTimer.scheduleTimeout() // fires after 5000 - * reconnectTimer.reset() - * reconnectTimer.scheduleTimeout() // fires after 1000 - */ -class Timer { - constructor(callback, timerCalc) { - this.callback = callback; - this.timerCalc = timerCalc; - this.timer = undefined; - this.tries = 0; - this.callback = callback; - this.timerCalc = timerCalc; + jsx_parseAttribute() { + let node = this.startNode(); + if (this.eat(tt.braceL)) { + this.expect(tt.ellipsis); + node.argument = this.parseMaybeAssign(); + this.expect(tt.braceR); + return this.finishNode(node, 'JSXSpreadAttribute'); + } + node.name = this.jsx_parseNamespacedName(); + node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null; + return this.finishNode(node, 'JSXAttribute'); } - reset() { - this.tries = 0; - clearTimeout(this.timer); + + // Parses JSX opening tag starting after '<'. + + jsx_parseOpeningElementAt(startPos, startLoc) { + let node = this.startNodeAt(startPos, startLoc); + node.attributes = []; + let nodeName = this.jsx_parseElementName(); + if (nodeName) node.name = nodeName; + while (this.type !== tt.slash && this.type !== tok.jsxTagEnd) + node.attributes.push(this.jsx_parseAttribute()); + node.selfClosing = this.eat(tt.slash); + this.expect(tok.jsxTagEnd); + return this.finishNode(node, nodeName ? 'JSXOpeningElement' : 'JSXOpeningFragment'); } - // Cancels any previous scheduleTimeout and schedules callback - scheduleTimeout() { - clearTimeout(this.timer); - this.timer = setTimeout(() => { - this.tries = this.tries + 1; - this.callback(); - }, this.timerCalc(this.tries + 1)); + + // Parses JSX closing tag starting after ' { + jsx_parseElementAt(startPos, startLoc) { + let node = this.startNodeAt(startPos, startLoc); + let children = []; + let openingElement = this.jsx_parseOpeningElementAt(startPos, startLoc); + let closingElement = null; -"use strict"; + if (!openingElement.selfClosing) { + contents: for (;;) { + switch (this.type) { + case tok.jsxTagStart: + startPos = this.start; startLoc = this.startLoc; + this.next(); + if (this.eat(tt.slash)) { + closingElement = this.jsx_parseClosingElementAt(startPos, startLoc); + break contents; + } + children.push(this.jsx_parseElementAt(startPos, startLoc)); + break; -/** - * Helpers to convert the change Payload into native JS types. - */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.toTimestampString = exports.toArray = exports.toJson = exports.toNumber = exports.toBoolean = exports.convertCell = exports.convertColumn = exports.convertChangeData = exports.PostgresTypes = void 0; -// Adapted from epgsql (src/epgsql_binary.erl), this module licensed under -// 3-clause BSD found here: https://raw.githubusercontent.com/epgsql/epgsql/devel/LICENSE -var PostgresTypes; -(function (PostgresTypes) { - PostgresTypes["abstime"] = "abstime"; - PostgresTypes["bool"] = "bool"; - PostgresTypes["date"] = "date"; - PostgresTypes["daterange"] = "daterange"; - PostgresTypes["float4"] = "float4"; - PostgresTypes["float8"] = "float8"; - PostgresTypes["int2"] = "int2"; - PostgresTypes["int4"] = "int4"; - PostgresTypes["int4range"] = "int4range"; - PostgresTypes["int8"] = "int8"; - PostgresTypes["int8range"] = "int8range"; - PostgresTypes["json"] = "json"; - PostgresTypes["jsonb"] = "jsonb"; - PostgresTypes["money"] = "money"; - PostgresTypes["numeric"] = "numeric"; - PostgresTypes["oid"] = "oid"; - PostgresTypes["reltime"] = "reltime"; - PostgresTypes["text"] = "text"; - PostgresTypes["time"] = "time"; - PostgresTypes["timestamp"] = "timestamp"; - PostgresTypes["timestamptz"] = "timestamptz"; - PostgresTypes["timetz"] = "timetz"; - PostgresTypes["tsrange"] = "tsrange"; - PostgresTypes["tstzrange"] = "tstzrange"; -})(PostgresTypes = exports.PostgresTypes || (exports.PostgresTypes = {})); -/** - * Takes an array of columns and an object of string values then converts each string value - * to its mapped type. - * - * @param {{name: String, type: String}[]} columns - * @param {Object} record - * @param {Object} options The map of various options that can be applied to the mapper - * @param {Array} options.skipTypes The array of types that should not be converted - * - * @example convertChangeData([{name: 'first_name', type: 'text'}, {name: 'age', type: 'int4'}], {first_name: 'Paul', age:'33'}, {}) - * //=>{ first_name: 'Paul', age: 33 } - */ -const convertChangeData = (columns, record, options = {}) => { - var _a; - const skipTypes = (_a = options.skipTypes) !== null && _a !== void 0 ? _a : []; - return Object.keys(record).reduce((acc, rec_key) => { - acc[rec_key] = (0, exports.convertColumn)(rec_key, columns, record, skipTypes); - return acc; - }, {}); -}; -exports.convertChangeData = convertChangeData; -/** - * Converts the value of an individual column. - * - * @param {String} columnName The column that you want to convert - * @param {{name: String, type: String}[]} columns All of the columns - * @param {Object} record The map of string values - * @param {Array} skipTypes An array of types that should not be converted - * @return {object} Useless information - * - * @example convertColumn('age', [{name: 'first_name', type: 'text'}, {name: 'age', type: 'int4'}], {first_name: 'Paul', age: '33'}, []) - * //=> 33 - * @example convertColumn('age', [{name: 'first_name', type: 'text'}, {name: 'age', type: 'int4'}], {first_name: 'Paul', age: '33'}, ['int4']) - * //=> "33" - */ -const convertColumn = (columnName, columns, record, skipTypes) => { - const column = columns.find((x) => x.name === columnName); - const colType = column === null || column === void 0 ? void 0 : column.type; - const value = record[columnName]; - if (colType && !skipTypes.includes(colType)) { - return (0, exports.convertCell)(colType, value); - } - return noop(value); -}; -exports.convertColumn = convertColumn; -/** - * If the value of the cell is `null`, returns null. - * Otherwise converts the string value to the correct type. - * @param {String} type A postgres column type - * @param {String} value The cell value - * - * @example convertCell('bool', 't') - * //=> true - * @example convertCell('int8', '10') - * //=> 10 - * @example convertCell('_int4', '{1,2,3,4}') - * //=> [1,2,3,4] - */ -const convertCell = (type, value) => { - // if data type is an array - if (type.charAt(0) === '_') { - const dataType = type.slice(1, type.length); - return (0, exports.toArray)(value, dataType); - } - // If not null, convert to correct type. - switch (type) { - case PostgresTypes.bool: - return (0, exports.toBoolean)(value); - case PostgresTypes.float4: - case PostgresTypes.float8: - case PostgresTypes.int2: - case PostgresTypes.int4: - case PostgresTypes.int8: - case PostgresTypes.numeric: - case PostgresTypes.oid: - return (0, exports.toNumber)(value); - case PostgresTypes.json: - case PostgresTypes.jsonb: - return (0, exports.toJson)(value); - case PostgresTypes.timestamp: - return (0, exports.toTimestampString)(value); // Format to be consistent with PostgREST - case PostgresTypes.abstime: // To allow users to cast it based on Timezone - case PostgresTypes.date: // To allow users to cast it based on Timezone - case PostgresTypes.daterange: - case PostgresTypes.int4range: - case PostgresTypes.int8range: - case PostgresTypes.money: - case PostgresTypes.reltime: // To allow users to cast it based on Timezone - case PostgresTypes.text: - case PostgresTypes.time: // To allow users to cast it based on Timezone - case PostgresTypes.timestamptz: // To allow users to cast it based on Timezone - case PostgresTypes.timetz: // To allow users to cast it based on Timezone - case PostgresTypes.tsrange: - case PostgresTypes.tstzrange: - return noop(value); - default: - // Return the value for remaining types - return noop(value); - } -}; -exports.convertCell = convertCell; -const noop = (value) => { - return value; -}; -const toBoolean = (value) => { - switch (value) { - case 't': - return true; - case 'f': - return false; - default: - return value; - } -}; -exports.toBoolean = toBoolean; -const toNumber = (value) => { - if (typeof value === 'string') { - const parsedValue = parseFloat(value); - if (!Number.isNaN(parsedValue)) { - return parsedValue; - } - } - return value; -}; -exports.toNumber = toNumber; -const toJson = (value) => { - if (typeof value === 'string') { - try { - return JSON.parse(value); - } - catch (error) { - console.log(`JSON parse error: ${error}`); - return value; - } - } - return value; -}; -exports.toJson = toJson; -/** - * Converts a Postgres Array into a native JS array - * - * @example toArray('{}', 'int4') - * //=> [] - * @example toArray('{"[2021-01-01,2021-12-31)","(2021-01-01,2021-12-32]"}', 'daterange') - * //=> ['[2021-01-01,2021-12-31)', '(2021-01-01,2021-12-32]'] - * @example toArray([1,2,3,4], 'int4') - * //=> [1,2,3,4] - */ -const toArray = (value, type) => { - if (typeof value !== 'string') { - return value; - } - const lastIdx = value.length - 1; - const closeBrace = value[lastIdx]; - const openBrace = value[0]; - // Confirm value is a Postgres array by checking curly brackets - if (openBrace === '{' && closeBrace === '}') { - let arr; - const valTrim = value.slice(1, lastIdx); - // TODO: find a better solution to separate Postgres array data - try { - arr = JSON.parse('[' + valTrim + ']'); - } - catch (_) { - // WARNING: splitting on comma does not cover all edge cases - arr = valTrim ? valTrim.split(',') : []; - } - return arr.map((val) => (0, exports.convertCell)(type, val)); - } - return value; -}; -exports.toArray = toArray; -/** - * Fixes timestamp to be ISO-8601. Swaps the space between the date and time for a 'T' - * See https://github.com/supabase/supabase/issues/18 - * - * @example toTimestampString('2019-09-10 00:00:00') - * //=> '2019-09-10T00:00:00' - */ -const toTimestampString = (value) => { - if (typeof value === 'string') { - return value.replace(' ', 'T'); - } - return value; -}; -exports.toTimestampString = toTimestampString; -//# sourceMappingURL=transformers.js.map - -/***/ }), - -/***/ 318: -/***/ ((__unused_webpack_module, exports) => { - -"use strict"; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.version = void 0; -exports.version = '2.8.4'; -//# sourceMappingURL=version.js.map - -/***/ }), + case tok.jsxText: + children.push(this.parseExprAtom()); + break; -/***/ 4249: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + case tt.braceL: + children.push(this.jsx_parseExpressionContainer()); + break; -"use strict"; + default: + this.unexpected(); + } + } + if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) { + this.raise( + closingElement.start, + 'Expected corresponding JSX closing tag for <' + getQualifiedJSXName(openingElement.name) + '>'); + } + } + let fragmentOrElement = openingElement.name ? 'Element' : 'Fragment'; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.StorageClient = void 0; -const StorageFileApi_1 = __importDefault(__nccwpck_require__(710)); -const StorageBucketApi_1 = __importDefault(__nccwpck_require__(3528)); -class StorageClient extends StorageBucketApi_1.default { - constructor(url, headers = {}, fetch) { - super(url, headers, fetch); - } - /** - * Perform file operation in a bucket. - * - * @param id The bucket id to operate on. - */ - from(id) { - return new StorageFileApi_1.default(this.url, this.headers, id, this.fetch); + node['opening' + fragmentOrElement] = openingElement; + node['closing' + fragmentOrElement] = closingElement; + node.children = children; + if (this.type === tt.relational && this.value === "<") { + this.raise(this.start, "Adjacent JSX elements must be wrapped in an enclosing tag"); + } + return this.finishNode(node, 'JSX' + fragmentOrElement); } -} -exports.StorageClient = StorageClient; -//# sourceMappingURL=StorageClient.js.map -/***/ }), + // Parse JSX text -/***/ 5852: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + jsx_parseText() { + let node = this.parseLiteral(this.value); + node.type = "JSXText"; + return node; + } -"use strict"; + // Parses entire JSX element from current position. -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; + jsx_parseElement() { + let startPos = this.start, startLoc = this.startLoc; + this.next(); + return this.jsx_parseElementAt(startPos, startLoc); } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __exportStar = (this && this.__exportStar) || function(m, exports) { - for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.StorageClient = void 0; -var StorageClient_1 = __nccwpck_require__(4249); -Object.defineProperty(exports, "StorageClient", ({ enumerable: true, get: function () { return StorageClient_1.StorageClient; } })); -__exportStar(__nccwpck_require__(7222), exports); -__exportStar(__nccwpck_require__(2758), exports); -//# sourceMappingURL=index.js.map - -/***/ }), -/***/ 9754: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + parseExprAtom(refShortHandDefaultPos) { + if (this.type === tok.jsxText) + return this.jsx_parseText(); + else if (this.type === tok.jsxTagStart) + return this.jsx_parseElement(); + else + return super.parseExprAtom(refShortHandDefaultPos); + } -"use strict"; + readToken(code) { + let context = this.curContext(); -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.DEFAULT_HEADERS = void 0; -const version_1 = __nccwpck_require__(4499); -exports.DEFAULT_HEADERS = { 'X-Client-Info': `storage-js/${version_1.version}` }; -//# sourceMappingURL=constants.js.map + if (context === tc_expr) return this.jsx_readToken(); -/***/ }), + if (context === tc_oTag || context === tc_cTag) { + if (isIdentifierStart(code)) return this.jsx_readWord(); -/***/ 2758: -/***/ ((__unused_webpack_module, exports) => { + if (code == 62) { + ++this.pos; + return this.finishToken(tok.jsxTagEnd); + } -"use strict"; + if ((code === 34 || code === 39) && context == tc_oTag) + return this.jsx_readString(code); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.StorageUnknownError = exports.StorageApiError = exports.isStorageError = exports.StorageError = void 0; -class StorageError extends Error { - constructor(message) { - super(message); - this.__isStorageError = true; - this.name = 'StorageError'; - } -} -exports.StorageError = StorageError; -function isStorageError(error) { - return typeof error === 'object' && error !== null && '__isStorageError' in error; -} -exports.isStorageError = isStorageError; -class StorageApiError extends StorageError { - constructor(message, status) { - super(message); - this.name = 'StorageApiError'; - this.status = status; - } - toJSON() { - return { - name: this.name, - message: this.message, - status: this.status, - }; - } -} -exports.StorageApiError = StorageApiError; -class StorageUnknownError extends StorageError { - constructor(message, originalError) { - super(message); - this.name = 'StorageUnknownError'; - this.originalError = originalError; + if (code === 60 && this.exprAllowed && this.input.charCodeAt(this.pos + 1) !== 33) { + ++this.pos; + return this.finishToken(tok.jsxTagStart); + } + return super.readToken(code); } -} -exports.StorageUnknownError = StorageUnknownError; -//# sourceMappingURL=errors.js.map - -/***/ }), - -/***/ 3146: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.remove = exports.put = exports.post = exports.get = void 0; -const errors_1 = __nccwpck_require__(2758); -const helpers_1 = __nccwpck_require__(5430); -const _getErrorMessage = (err) => err.msg || err.message || err.error_description || err.error || JSON.stringify(err); -const handleError = (error, reject) => __awaiter(void 0, void 0, void 0, function* () { - const Res = yield (0, helpers_1.resolveResponse)(); - if (error instanceof Res) { - error - .json() - .then((err) => { - reject(new errors_1.StorageApiError(_getErrorMessage(err), error.status || 500)); - }) - .catch((err) => { - reject(new errors_1.StorageUnknownError(_getErrorMessage(err), err)); - }); - } - else { - reject(new errors_1.StorageUnknownError(_getErrorMessage(error), error)); - } -}); -const _getRequestParams = (method, options, parameters, body) => { - const params = { method, headers: (options === null || options === void 0 ? void 0 : options.headers) || {} }; - if (method === 'GET') { - return params; + updateContext(prevType) { + if (this.type == tt.braceL) { + var curContext = this.curContext(); + if (curContext == tc_oTag) this.context.push(tokContexts.b_expr); + else if (curContext == tc_expr) this.context.push(tokContexts.b_tmpl); + else super.updateContext(prevType); + this.exprAllowed = true; + } else if (this.type === tt.slash && prevType === tok.jsxTagStart) { + this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore + this.context.push(tc_cTag); // reconsider as closing tag context + this.exprAllowed = false; + } else { + return super.updateContext(prevType); + } } - params.headers = Object.assign({ 'Content-Type': 'application/json' }, options === null || options === void 0 ? void 0 : options.headers); - params.body = JSON.stringify(body); - return Object.assign(Object.assign({}, params), parameters); -}; -function _handleRequest(fetcher, method, url, options, parameters, body) { - return __awaiter(this, void 0, void 0, function* () { - return new Promise((resolve, reject) => { - fetcher(url, _getRequestParams(method, options, parameters, body)) - .then((result) => { - if (!result.ok) - throw result; - if (options === null || options === void 0 ? void 0 : options.noResolveJson) - return result; - return result.json(); - }) - .then((data) => resolve(data)) - .catch((error) => handleError(error, reject)); - }); - }); -} -function get(fetcher, url, options, parameters) { - return __awaiter(this, void 0, void 0, function* () { - return _handleRequest(fetcher, 'GET', url, options, parameters); - }); -} -exports.get = get; -function post(fetcher, url, body, options, parameters) { - return __awaiter(this, void 0, void 0, function* () { - return _handleRequest(fetcher, 'POST', url, options, parameters, body); - }); -} -exports.post = post; -function put(fetcher, url, body, options, parameters) { - return __awaiter(this, void 0, void 0, function* () { - return _handleRequest(fetcher, 'PUT', url, options, parameters, body); - }); -} -exports.put = put; -function remove(fetcher, url, body, options, parameters) { - return __awaiter(this, void 0, void 0, function* () { - return _handleRequest(fetcher, 'DELETE', url, options, parameters, body); - }); + }; } -exports.remove = remove; -//# sourceMappingURL=fetch.js.map - -/***/ }), - -/***/ 5430: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.resolveResponse = exports.resolveFetch = void 0; -const resolveFetch = (customFetch) => { - let _fetch; - if (customFetch) { - _fetch = customFetch; - } - else if (typeof fetch === 'undefined') { - _fetch = (...args) => Promise.resolve().then(() => __importStar(__nccwpck_require__(2668))).then(({ default: fetch }) => fetch(...args)); - } - else { - _fetch = fetch; - } - return (...args) => _fetch(...args); -}; -exports.resolveFetch = resolveFetch; -const resolveResponse = () => __awaiter(void 0, void 0, void 0, function* () { - if (typeof Response === 'undefined') { - // @ts-ignore - return (yield Promise.resolve().then(() => __importStar(__nccwpck_require__(2668)))).Response; - } - return Response; -}); -exports.resolveResponse = resolveResponse; -//# sourceMappingURL=helpers.js.map - -/***/ }), - -/***/ 7222: -/***/ ((__unused_webpack_module, exports) => { - -"use strict"; - -Object.defineProperty(exports, "__esModule", ({ value: true })); -//# sourceMappingURL=types.js.map - -/***/ }), - -/***/ 4499: -/***/ ((__unused_webpack_module, exports) => { - -"use strict"; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.version = void 0; -// generated by genversion -exports.version = '2.5.4'; -//# sourceMappingURL=version.js.map /***/ }), -/***/ 3528: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; +/***/ 3096: +/***/ ((module) => { + +module.exports = { + quot: '\u0022', + amp: '&', + apos: '\u0027', + lt: '<', + gt: '>', + nbsp: '\u00A0', + iexcl: '\u00A1', + cent: '\u00A2', + pound: '\u00A3', + curren: '\u00A4', + yen: '\u00A5', + brvbar: '\u00A6', + sect: '\u00A7', + uml: '\u00A8', + copy: '\u00A9', + ordf: '\u00AA', + laquo: '\u00AB', + not: '\u00AC', + shy: '\u00AD', + reg: '\u00AE', + macr: '\u00AF', + deg: '\u00B0', + plusmn: '\u00B1', + sup2: '\u00B2', + sup3: '\u00B3', + acute: '\u00B4', + micro: '\u00B5', + para: '\u00B6', + middot: '\u00B7', + cedil: '\u00B8', + sup1: '\u00B9', + ordm: '\u00BA', + raquo: '\u00BB', + frac14: '\u00BC', + frac12: '\u00BD', + frac34: '\u00BE', + iquest: '\u00BF', + Agrave: '\u00C0', + Aacute: '\u00C1', + Acirc: '\u00C2', + Atilde: '\u00C3', + Auml: '\u00C4', + Aring: '\u00C5', + AElig: '\u00C6', + Ccedil: '\u00C7', + Egrave: '\u00C8', + Eacute: '\u00C9', + Ecirc: '\u00CA', + Euml: '\u00CB', + Igrave: '\u00CC', + Iacute: '\u00CD', + Icirc: '\u00CE', + Iuml: '\u00CF', + ETH: '\u00D0', + Ntilde: '\u00D1', + Ograve: '\u00D2', + Oacute: '\u00D3', + Ocirc: '\u00D4', + Otilde: '\u00D5', + Ouml: '\u00D6', + times: '\u00D7', + Oslash: '\u00D8', + Ugrave: '\u00D9', + Uacute: '\u00DA', + Ucirc: '\u00DB', + Uuml: '\u00DC', + Yacute: '\u00DD', + THORN: '\u00DE', + szlig: '\u00DF', + agrave: '\u00E0', + aacute: '\u00E1', + acirc: '\u00E2', + atilde: '\u00E3', + auml: '\u00E4', + aring: '\u00E5', + aelig: '\u00E6', + ccedil: '\u00E7', + egrave: '\u00E8', + eacute: '\u00E9', + ecirc: '\u00EA', + euml: '\u00EB', + igrave: '\u00EC', + iacute: '\u00ED', + icirc: '\u00EE', + iuml: '\u00EF', + eth: '\u00F0', + ntilde: '\u00F1', + ograve: '\u00F2', + oacute: '\u00F3', + ocirc: '\u00F4', + otilde: '\u00F5', + ouml: '\u00F6', + divide: '\u00F7', + oslash: '\u00F8', + ugrave: '\u00F9', + uacute: '\u00FA', + ucirc: '\u00FB', + uuml: '\u00FC', + yacute: '\u00FD', + thorn: '\u00FE', + yuml: '\u00FF', + OElig: '\u0152', + oelig: '\u0153', + Scaron: '\u0160', + scaron: '\u0161', + Yuml: '\u0178', + fnof: '\u0192', + circ: '\u02C6', + tilde: '\u02DC', + Alpha: '\u0391', + Beta: '\u0392', + Gamma: '\u0393', + Delta: '\u0394', + Epsilon: '\u0395', + Zeta: '\u0396', + Eta: '\u0397', + Theta: '\u0398', + Iota: '\u0399', + Kappa: '\u039A', + Lambda: '\u039B', + Mu: '\u039C', + Nu: '\u039D', + Xi: '\u039E', + Omicron: '\u039F', + Pi: '\u03A0', + Rho: '\u03A1', + Sigma: '\u03A3', + Tau: '\u03A4', + Upsilon: '\u03A5', + Phi: '\u03A6', + Chi: '\u03A7', + Psi: '\u03A8', + Omega: '\u03A9', + alpha: '\u03B1', + beta: '\u03B2', + gamma: '\u03B3', + delta: '\u03B4', + epsilon: '\u03B5', + zeta: '\u03B6', + eta: '\u03B7', + theta: '\u03B8', + iota: '\u03B9', + kappa: '\u03BA', + lambda: '\u03BB', + mu: '\u03BC', + nu: '\u03BD', + xi: '\u03BE', + omicron: '\u03BF', + pi: '\u03C0', + rho: '\u03C1', + sigmaf: '\u03C2', + sigma: '\u03C3', + tau: '\u03C4', + upsilon: '\u03C5', + phi: '\u03C6', + chi: '\u03C7', + psi: '\u03C8', + omega: '\u03C9', + thetasym: '\u03D1', + upsih: '\u03D2', + piv: '\u03D6', + ensp: '\u2002', + emsp: '\u2003', + thinsp: '\u2009', + zwnj: '\u200C', + zwj: '\u200D', + lrm: '\u200E', + rlm: '\u200F', + ndash: '\u2013', + mdash: '\u2014', + lsquo: '\u2018', + rsquo: '\u2019', + sbquo: '\u201A', + ldquo: '\u201C', + rdquo: '\u201D', + bdquo: '\u201E', + dagger: '\u2020', + Dagger: '\u2021', + bull: '\u2022', + hellip: '\u2026', + permil: '\u2030', + prime: '\u2032', + Prime: '\u2033', + lsaquo: '\u2039', + rsaquo: '\u203A', + oline: '\u203E', + frasl: '\u2044', + euro: '\u20AC', + image: '\u2111', + weierp: '\u2118', + real: '\u211C', + trade: '\u2122', + alefsym: '\u2135', + larr: '\u2190', + uarr: '\u2191', + rarr: '\u2192', + darr: '\u2193', + harr: '\u2194', + crarr: '\u21B5', + lArr: '\u21D0', + uArr: '\u21D1', + rArr: '\u21D2', + dArr: '\u21D3', + hArr: '\u21D4', + forall: '\u2200', + part: '\u2202', + exist: '\u2203', + empty: '\u2205', + nabla: '\u2207', + isin: '\u2208', + notin: '\u2209', + ni: '\u220B', + prod: '\u220F', + sum: '\u2211', + minus: '\u2212', + lowast: '\u2217', + radic: '\u221A', + prop: '\u221D', + infin: '\u221E', + ang: '\u2220', + and: '\u2227', + or: '\u2228', + cap: '\u2229', + cup: '\u222A', + 'int': '\u222B', + there4: '\u2234', + sim: '\u223C', + cong: '\u2245', + asymp: '\u2248', + ne: '\u2260', + equiv: '\u2261', + le: '\u2264', + ge: '\u2265', + sub: '\u2282', + sup: '\u2283', + nsub: '\u2284', + sube: '\u2286', + supe: '\u2287', + oplus: '\u2295', + otimes: '\u2297', + perp: '\u22A5', + sdot: '\u22C5', + lceil: '\u2308', + rceil: '\u2309', + lfloor: '\u230A', + rfloor: '\u230B', + lang: '\u2329', + rang: '\u232A', + loz: '\u25CA', + spades: '\u2660', + clubs: '\u2663', + hearts: '\u2665', + diams: '\u2666' +}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -const constants_1 = __nccwpck_require__(9754); -const errors_1 = __nccwpck_require__(2758); -const fetch_1 = __nccwpck_require__(3146); -const helpers_1 = __nccwpck_require__(5430); -class StorageBucketApi { - constructor(url, headers = {}, fetch) { - this.url = url; - this.headers = Object.assign(Object.assign({}, constants_1.DEFAULT_HEADERS), headers); - this.fetch = (0, helpers_1.resolveFetch)(fetch); - } - /** - * Retrieves the details of all Storage buckets within an existing project. - */ - listBuckets() { - return __awaiter(this, void 0, void 0, function* () { - try { - const data = yield (0, fetch_1.get)(this.fetch, `${this.url}/bucket`, { headers: this.headers }); - return { data, error: null }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - /** - * Retrieves the details of an existing Storage bucket. - * - * @param id The unique identifier of the bucket you would like to retrieve. - */ - getBucket(id) { - return __awaiter(this, void 0, void 0, function* () { - try { - const data = yield (0, fetch_1.get)(this.fetch, `${this.url}/bucket/${id}`, { headers: this.headers }); - return { data, error: null }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - /** - * Creates a new Storage bucket - * - * @param id A unique identifier for the bucket you are creating. - * @param options.public The visibility of the bucket. Public buckets don't require an authorization token to download objects, but still require a valid token for all other operations. By default, buckets are private. - * @param options.fileSizeLimit specifies the max file size in bytes that can be uploaded to this bucket. - * The global file size limit takes precedence over this value. - * The default value is null, which doesn't set a per bucket file size limit. - * @param options.allowedMimeTypes specifies the allowed mime types that this bucket can accept during upload. - * The default value is null, which allows files with all mime types to be uploaded. - * Each mime type specified can be a wildcard, e.g. image/*, or a specific mime type, e.g. image/png. - * @returns newly created bucket id - */ - createBucket(id, options = { - public: false, - }) { - return __awaiter(this, void 0, void 0, function* () { - try { - const data = yield (0, fetch_1.post)(this.fetch, `${this.url}/bucket`, { - id, - name: id, - public: options.public, - file_size_limit: options.fileSizeLimit, - allowed_mime_types: options.allowedMimeTypes, - }, { headers: this.headers }); - return { data, error: null }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - /** - * Updates a Storage bucket - * - * @param id A unique identifier for the bucket you are updating. - * @param options.public The visibility of the bucket. Public buckets don't require an authorization token to download objects, but still require a valid token for all other operations. - * @param options.fileSizeLimit specifies the max file size in bytes that can be uploaded to this bucket. - * The global file size limit takes precedence over this value. - * The default value is null, which doesn't set a per bucket file size limit. - * @param options.allowedMimeTypes specifies the allowed mime types that this bucket can accept during upload. - * The default value is null, which allows files with all mime types to be uploaded. - * Each mime type specified can be a wildcard, e.g. image/*, or a specific mime type, e.g. image/png. - */ - updateBucket(id, options) { - return __awaiter(this, void 0, void 0, function* () { - try { - const data = yield (0, fetch_1.put)(this.fetch, `${this.url}/bucket/${id}`, { - id, - name: id, - public: options.public, - file_size_limit: options.fileSizeLimit, - allowed_mime_types: options.allowedMimeTypes, - }, { headers: this.headers }); - return { data, error: null }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - /** - * Removes all objects inside a single bucket. - * - * @param id The unique identifier of the bucket you would like to empty. - */ - emptyBucket(id) { - return __awaiter(this, void 0, void 0, function* () { - try { - const data = yield (0, fetch_1.post)(this.fetch, `${this.url}/bucket/${id}/empty`, {}, { headers: this.headers }); - return { data, error: null }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - /** - * Deletes an existing bucket. A bucket can't be deleted with existing objects inside it. - * You must first `empty()` the bucket. - * - * @param id The unique identifier of the bucket you would like to delete. - */ - deleteBucket(id) { - return __awaiter(this, void 0, void 0, function* () { - try { - const data = yield (0, fetch_1.remove)(this.fetch, `${this.url}/bucket/${id}`, {}, { headers: this.headers }); - return { data, error: null }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } -} -exports["default"] = StorageBucketApi; -//# sourceMappingURL=StorageBucketApi.js.map /***/ }), -/***/ 710: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 390: +/***/ (function(__unused_webpack_module, exports) { -"use strict"; +(function (global, factory) { + true ? factory(exports) : + 0; +})(this, (function (exports) { 'use strict'; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -const errors_1 = __nccwpck_require__(2758); -const fetch_1 = __nccwpck_require__(3146); -const helpers_1 = __nccwpck_require__(5430); -const DEFAULT_SEARCH_OPTIONS = { - limit: 100, - offset: 0, - sortBy: { - column: 'name', - order: 'asc', - }, -}; -const DEFAULT_FILE_OPTIONS = { - cacheControl: '3600', - contentType: 'text/plain;charset=UTF-8', - upsert: false, -}; -class StorageFileApi { - constructor(url, headers = {}, bucketId, fetch) { - this.url = url; - this.headers = headers; - this.bucketId = bucketId; - this.fetch = (0, helpers_1.resolveFetch)(fetch); - } - /** - * Uploads a file to an existing bucket or replaces an existing file at the specified path with a new one. - * - * @param method HTTP method. - * @param path The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload. - * @param fileBody The body of the file to be stored in the bucket. - */ - uploadOrUpdate(method, path, fileBody, fileOptions) { - return __awaiter(this, void 0, void 0, function* () { - try { - let body; - const options = Object.assign(Object.assign({}, DEFAULT_FILE_OPTIONS), fileOptions); - const headers = Object.assign(Object.assign({}, this.headers), (method === 'POST' && { 'x-upsert': String(options.upsert) })); - if (typeof Blob !== 'undefined' && fileBody instanceof Blob) { - body = new FormData(); - body.append('cacheControl', options.cacheControl); - body.append('', fileBody); - } - else if (typeof FormData !== 'undefined' && fileBody instanceof FormData) { - body = fileBody; - body.append('cacheControl', options.cacheControl); - } - else { - body = fileBody; - headers['cache-control'] = `max-age=${options.cacheControl}`; - headers['content-type'] = options.contentType; - } - const cleanPath = this._removeEmptyFolders(path); - const _path = this._getFinalPath(cleanPath); - const res = yield this.fetch(`${this.url}/object/${_path}`, Object.assign({ method, body: body, headers }, ((options === null || options === void 0 ? void 0 : options.duplex) ? { duplex: options.duplex } : {}))); - if (res.ok) { - return { - data: { path: cleanPath }, - error: null, - }; - } - else { - const error = yield res.json(); - return { data: null, error }; - } - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - /** - * Uploads a file to an existing bucket. - * - * @param path The file path, including the file name. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload. - * @param fileBody The body of the file to be stored in the bucket. - */ - upload(path, fileBody, fileOptions) { - return __awaiter(this, void 0, void 0, function* () { - return this.uploadOrUpdate('POST', path, fileBody, fileOptions); - }); - } - /** - * Upload a file with a token generated from `createSignedUploadUrl`. - * @param path The file path, including the file name. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to upload. - * @param token The token generated from `createSignedUploadUrl` - * @param fileBody The body of the file to be stored in the bucket. - */ - uploadToSignedUrl(path, token, fileBody, fileOptions) { - return __awaiter(this, void 0, void 0, function* () { - const cleanPath = this._removeEmptyFolders(path); - const _path = this._getFinalPath(cleanPath); - const url = new URL(this.url + `/object/upload/sign/${_path}`); - url.searchParams.set('token', token); - try { - let body; - const options = Object.assign({ upsert: DEFAULT_FILE_OPTIONS.upsert }, fileOptions); - const headers = Object.assign(Object.assign({}, this.headers), { 'x-upsert': String(options.upsert) }); - if (typeof Blob !== 'undefined' && fileBody instanceof Blob) { - body = new FormData(); - body.append('cacheControl', options.cacheControl); - body.append('', fileBody); - } - else if (typeof FormData !== 'undefined' && fileBody instanceof FormData) { - body = fileBody; - body.append('cacheControl', options.cacheControl); - } - else { - body = fileBody; - headers['cache-control'] = `max-age=${options.cacheControl}`; - headers['content-type'] = options.contentType; - } - const res = yield this.fetch(url.toString(), { - method: 'PUT', - body: body, - headers, - }); - if (res.ok) { - return { - data: { path: cleanPath }, - error: null, - }; - } - else { - const error = yield res.json(); - return { data: null, error }; - } - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - /** - * Creates a signed upload URL. - * Signed upload URLs can be used to upload files to the bucket without further authentication. - * They are valid for 2 hours. - * @param path The file path, including the current file name. For example `folder/image.png`. - */ - createSignedUploadUrl(path) { - return __awaiter(this, void 0, void 0, function* () { - try { - let _path = this._getFinalPath(path); - const data = yield (0, fetch_1.post)(this.fetch, `${this.url}/object/upload/sign/${_path}`, {}, { headers: this.headers }); - const url = new URL(this.url + data.url); - const token = url.searchParams.get('token'); - if (!token) { - throw new errors_1.StorageError('No token returned by API'); - } - return { data: { signedUrl: url.toString(), path, token }, error: null }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - /** - * Replaces an existing file at the specified path with a new one. - * - * @param path The relative file path. Should be of the format `folder/subfolder/filename.png`. The bucket must already exist before attempting to update. - * @param fileBody The body of the file to be stored in the bucket. - */ - update(path, fileBody, fileOptions) { - return __awaiter(this, void 0, void 0, function* () { - return this.uploadOrUpdate('PUT', path, fileBody, fileOptions); - }); - } - /** - * Moves an existing file to a new path in the same bucket. - * - * @param fromPath The original file path, including the current file name. For example `folder/image.png`. - * @param toPath The new file path, including the new file name. For example `folder/image-new.png`. - */ - move(fromPath, toPath) { - return __awaiter(this, void 0, void 0, function* () { - try { - const data = yield (0, fetch_1.post)(this.fetch, `${this.url}/object/move`, { bucketId: this.bucketId, sourceKey: fromPath, destinationKey: toPath }, { headers: this.headers }); - return { data, error: null }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - /** - * Copies an existing file to a new path in the same bucket. - * - * @param fromPath The original file path, including the current file name. For example `folder/image.png`. - * @param toPath The new file path, including the new file name. For example `folder/image-copy.png`. - */ - copy(fromPath, toPath) { - return __awaiter(this, void 0, void 0, function* () { - try { - const data = yield (0, fetch_1.post)(this.fetch, `${this.url}/object/copy`, { bucketId: this.bucketId, sourceKey: fromPath, destinationKey: toPath }, { headers: this.headers }); - return { data: { path: data.Key }, error: null }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - /** - * Creates a signed URL. Use a signed URL to share a file for a fixed amount of time. - * - * @param path The file path, including the current file name. For example `folder/image.png`. - * @param expiresIn The number of seconds until the signed URL expires. For example, `60` for a URL which is valid for one minute. - * @param options.download triggers the file as a download if set to true. Set this parameter as the name of the file if you want to trigger the download with a different filename. - * @param options.transform Transform the asset before serving it to the client. - */ - createSignedUrl(path, expiresIn, options) { - return __awaiter(this, void 0, void 0, function* () { - try { - let _path = this._getFinalPath(path); - let data = yield (0, fetch_1.post)(this.fetch, `${this.url}/object/sign/${_path}`, Object.assign({ expiresIn }, ((options === null || options === void 0 ? void 0 : options.transform) ? { transform: options.transform } : {})), { headers: this.headers }); - const downloadQueryParam = (options === null || options === void 0 ? void 0 : options.download) - ? `&download=${options.download === true ? '' : options.download}` - : ''; - const signedUrl = encodeURI(`${this.url}${data.signedURL}${downloadQueryParam}`); - data = { signedUrl }; - return { data, error: null }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); + // This file was generated. Do not modify manually! + var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 81, 2, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 9, 5351, 0, 7, 14, 13835, 9, 87, 9, 39, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4706, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 983, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; + + // This file was generated. Do not modify manually! + var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 68, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 4026, 582, 8634, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8936, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 757, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4153, 7, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938, 6, 4191]; + + // This file was generated. Do not modify manually! + var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0898-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; + + // This file was generated. Do not modify manually! + var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ca\ua7d0\ua7d1\ua7d3\ua7d5-\ua7d9\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; + + // These are a run-length and offset encoded representation of the + + // Reserved word lists for various dialects of the language + + var reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" + }; + + // And the keywords + + var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"; + + var keywords$1 = { + 5: ecma5AndLessKeywords, + "5module": ecma5AndLessKeywords + " export import", + 6: ecma5AndLessKeywords + " const class extends export import super" + }; + + var keywordRelationalOperator = /^in(stanceof)?$/; + + // ## Character categories + + var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); + var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); + + // This has a complexity linear to the value of the code. The + // assumption is that looking up astral identifier characters is + // rare. + function isInAstralSet(code, set) { + var pos = 0x10000; + for (var i = 0; i < set.length; i += 2) { + pos += set[i]; + if (pos > code) { return false } + pos += set[i + 1]; + if (pos >= code) { return true } } - /** - * Creates multiple signed URLs. Use a signed URL to share a file for a fixed amount of time. - * - * @param paths The file paths to be downloaded, including the current file names. For example `['folder/image.png', 'folder2/image2.png']`. - * @param expiresIn The number of seconds until the signed URLs expire. For example, `60` for URLs which are valid for one minute. - * @param options.download triggers the file as a download if set to true. Set this parameter as the name of the file if you want to trigger the download with a different filename. - */ - createSignedUrls(paths, expiresIn, options) { - return __awaiter(this, void 0, void 0, function* () { - try { - const data = yield (0, fetch_1.post)(this.fetch, `${this.url}/object/sign/${this.bucketId}`, { expiresIn, paths }, { headers: this.headers }); - const downloadQueryParam = (options === null || options === void 0 ? void 0 : options.download) - ? `&download=${options.download === true ? '' : options.download}` - : ''; - return { - data: data.map((datum) => (Object.assign(Object.assign({}, datum), { signedUrl: datum.signedURL - ? encodeURI(`${this.url}${datum.signedURL}${downloadQueryParam}`) - : null }))), - error: null, - }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - /** - * Downloads a file from a private bucket. For public buckets, make a request to the URL returned from `getPublicUrl` instead. - * - * @param path The full path and file name of the file to be downloaded. For example `folder/image.png`. - * @param options.transform Transform the asset before serving it to the client. - */ - download(path, options) { - return __awaiter(this, void 0, void 0, function* () { - const wantsTransformation = typeof (options === null || options === void 0 ? void 0 : options.transform) !== 'undefined'; - const renderPath = wantsTransformation ? 'render/image/authenticated' : 'object'; - const transformationQuery = this.transformOptsToQueryString((options === null || options === void 0 ? void 0 : options.transform) || {}); - const queryString = transformationQuery ? `?${transformationQuery}` : ''; - try { - const _path = this._getFinalPath(path); - const res = yield (0, fetch_1.get)(this.fetch, `${this.url}/${renderPath}/${_path}${queryString}`, { - headers: this.headers, - noResolveJson: true, - }); - const data = yield res.blob(); - return { data, error: null }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - /** - * A simple convenience function to get the URL for an asset in a public bucket. If you do not want to use this function, you can construct the public URL by concatenating the bucket URL with the path to the asset. - * This function does not verify if the bucket is public. If a public URL is created for a bucket which is not public, you will not be able to download the asset. - * - * @param path The path and name of the file to generate the public URL for. For example `folder/image.png`. - * @param options.download Triggers the file as a download if set to true. Set this parameter as the name of the file if you want to trigger the download with a different filename. - * @param options.transform Transform the asset before serving it to the client. - */ - getPublicUrl(path, options) { - const _path = this._getFinalPath(path); - const _queryString = []; - const downloadQueryParam = (options === null || options === void 0 ? void 0 : options.download) - ? `download=${options.download === true ? '' : options.download}` - : ''; - if (downloadQueryParam !== '') { - _queryString.push(downloadQueryParam); - } - const wantsTransformation = typeof (options === null || options === void 0 ? void 0 : options.transform) !== 'undefined'; - const renderPath = wantsTransformation ? 'render/image' : 'object'; - const transformationQuery = this.transformOptsToQueryString((options === null || options === void 0 ? void 0 : options.transform) || {}); - if (transformationQuery !== '') { - _queryString.push(transformationQuery); - } - let queryString = _queryString.join('&'); - if (queryString !== '') { - queryString = `?${queryString}`; - } - return { - data: { publicUrl: encodeURI(`${this.url}/${renderPath}/public/${_path}${queryString}`) }, - }; - } - /** - * Deletes files within the same bucket - * - * @param paths An array of files to delete, including the path and file name. For example [`'folder/image.png'`]. - */ - remove(paths) { - return __awaiter(this, void 0, void 0, function* () { - try { - const data = yield (0, fetch_1.remove)(this.fetch, `${this.url}/object/${this.bucketId}`, { prefixes: paths }, { headers: this.headers }); - return { data, error: null }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - /** - * Get file metadata - * @param id the file id to retrieve metadata - */ - // async getMetadata( - // id: string - // ): Promise< - // | { - // data: Metadata - // error: null - // } - // | { - // data: null - // error: StorageError - // } - // > { - // try { - // const data = await get(this.fetch, `${this.url}/metadata/${id}`, { headers: this.headers }) - // return { data, error: null } - // } catch (error) { - // if (isStorageError(error)) { - // return { data: null, error } - // } - // throw error - // } - // } - /** - * Update file metadata - * @param id the file id to update metadata - * @param meta the new file metadata - */ - // async updateMetadata( - // id: string, - // meta: Metadata - // ): Promise< - // | { - // data: Metadata - // error: null - // } - // | { - // data: null - // error: StorageError - // } - // > { - // try { - // const data = await post( - // this.fetch, - // `${this.url}/metadata/${id}`, - // { ...meta }, - // { headers: this.headers } - // ) - // return { data, error: null } - // } catch (error) { - // if (isStorageError(error)) { - // return { data: null, error } - // } - // throw error - // } - // } - /** - * Lists all the files within a bucket. - * @param path The folder path. - */ - list(path, options, parameters) { - return __awaiter(this, void 0, void 0, function* () { - try { - const body = Object.assign(Object.assign(Object.assign({}, DEFAULT_SEARCH_OPTIONS), options), { prefix: path || '' }); - const data = yield (0, fetch_1.post)(this.fetch, `${this.url}/object/list/${this.bucketId}`, body, { headers: this.headers }, parameters); - return { data, error: null }; - } - catch (error) { - if ((0, errors_1.isStorageError)(error)) { - return { data: null, error }; - } - throw error; - } - }); - } - _getFinalPath(path) { - return `${this.bucketId}/${path}`; - } - _removeEmptyFolders(path) { - return path.replace(/^\/|\/$/g, '').replace(/\/+/g, '/'); - } - transformOptsToQueryString(transform) { - const params = []; - if (transform.width) { - params.push(`width=${transform.width}`); - } - if (transform.height) { - params.push(`height=${transform.height}`); - } - if (transform.resize) { - params.push(`resize=${transform.resize}`); - } - if (transform.format) { - params.push(`format=${transform.format}`); - } - if (transform.quality) { - params.push(`quality=${transform.quality}`); - } - return params.join('&'); - } -} -exports["default"] = StorageFileApi; -//# sourceMappingURL=StorageFileApi.js.map + return false + } -/***/ }), + // Test whether a given character code starts an identifier. -/***/ 1807: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + function isIdentifierStart(code, astral) { + if (code < 65) { return code === 36 } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) + } -"use strict"; + // Test whether a given character is part of an identifier. -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -const functions_js_1 = __nccwpck_require__(8519); -const postgrest_js_1 = __nccwpck_require__(720); -const realtime_js_1 = __nccwpck_require__(442); -const storage_js_1 = __nccwpck_require__(5852); -const constants_1 = __nccwpck_require__(4868); -const fetch_1 = __nccwpck_require__(785); -const helpers_1 = __nccwpck_require__(3575); -const SupabaseAuthClient_1 = __nccwpck_require__(7620); -const DEFAULT_GLOBAL_OPTIONS = { - headers: constants_1.DEFAULT_HEADERS, -}; -const DEFAULT_DB_OPTIONS = { - schema: 'public', -}; -const DEFAULT_AUTH_OPTIONS = { - autoRefreshToken: true, - persistSession: true, - detectSessionInUrl: true, - flowType: 'implicit', -}; -const DEFAULT_REALTIME_OPTIONS = {}; -/** - * Supabase Client. - * - * An isomorphic Javascript client for interacting with Postgres. - */ -class SupabaseClient { - /** - * Create a new client for use in the browser. - * @param supabaseUrl The unique Supabase URL which is supplied when you create a new project in your project dashboard. - * @param supabaseKey The unique Supabase Key which is supplied when you create a new project in your project dashboard. - * @param options.db.schema You can switch in between schemas. The schema needs to be on the list of exposed schemas inside Supabase. - * @param options.auth.autoRefreshToken Set to "true" if you want to automatically refresh the token before expiring. - * @param options.auth.persistSession Set to "true" if you want to automatically save the user session into local storage. - * @param options.auth.detectSessionInUrl Set to "true" if you want to automatically detects OAuth grants in the URL and signs in the user. - * @param options.realtime Options passed along to realtime-js constructor. - * @param options.global.fetch A custom fetch implementation. - * @param options.global.headers Any additional headers to send with each network request. - */ - constructor(supabaseUrl, supabaseKey, options) { - var _a, _b, _c, _d, _e, _f, _g, _h; - this.supabaseUrl = supabaseUrl; - this.supabaseKey = supabaseKey; - if (!supabaseUrl) - throw new Error('supabaseUrl is required.'); - if (!supabaseKey) - throw new Error('supabaseKey is required.'); - const _supabaseUrl = (0, helpers_1.stripTrailingSlash)(supabaseUrl); - this.realtimeUrl = `${_supabaseUrl}/realtime/v1`.replace(/^http/i, 'ws'); - this.authUrl = `${_supabaseUrl}/auth/v1`; - this.storageUrl = `${_supabaseUrl}/storage/v1`; - this.functionsUrl = `${_supabaseUrl}/functions/v1`; - // default storage key uses the supabase project ref as a namespace - const defaultStorageKey = `sb-${new URL(this.authUrl).hostname.split('.')[0]}-auth-token`; - const DEFAULTS = { - db: DEFAULT_DB_OPTIONS, - realtime: DEFAULT_REALTIME_OPTIONS, - auth: Object.assign(Object.assign({}, DEFAULT_AUTH_OPTIONS), { storageKey: defaultStorageKey }), - global: DEFAULT_GLOBAL_OPTIONS, - }; - const settings = (0, helpers_1.applySettingDefaults)(options !== null && options !== void 0 ? options : {}, DEFAULTS); - this.storageKey = (_b = (_a = settings.auth) === null || _a === void 0 ? void 0 : _a.storageKey) !== null && _b !== void 0 ? _b : ''; - this.headers = (_d = (_c = settings.global) === null || _c === void 0 ? void 0 : _c.headers) !== null && _d !== void 0 ? _d : {}; - this.auth = this._initSupabaseAuthClient((_e = settings.auth) !== null && _e !== void 0 ? _e : {}, this.headers, (_f = settings.global) === null || _f === void 0 ? void 0 : _f.fetch); - this.fetch = (0, fetch_1.fetchWithAuth)(supabaseKey, this._getAccessToken.bind(this), (_g = settings.global) === null || _g === void 0 ? void 0 : _g.fetch); - this.realtime = this._initRealtimeClient(Object.assign({ headers: this.headers }, settings.realtime)); - this.rest = new postgrest_js_1.PostgrestClient(`${_supabaseUrl}/rest/v1`, { - headers: this.headers, - schema: (_h = settings.db) === null || _h === void 0 ? void 0 : _h.schema, - fetch: this.fetch, - }); - this._listenForAuthEvents(); - } - /** - * Supabase Functions allows you to deploy and invoke edge functions. - */ - get functions() { - return new functions_js_1.FunctionsClient(this.functionsUrl, { - headers: this.headers, - customFetch: this.fetch, - }); - } - /** - * Supabase Storage allows you to manage user-generated content, such as photos or videos. - */ - get storage() { - return new storage_js_1.StorageClient(this.storageUrl, this.headers, this.fetch); - } - /** - * Perform a query on a table or a view. - * - * @param relation - The table or view name to query - */ - from(relation) { - return this.rest.from(relation); - } - /** - * Perform a query on a schema distinct from the default schema supplied via - * the `options.db.schema` constructor parameter. - * - * The schema needs to be on the list of exposed schemas inside Supabase. - * - * @param schema - The name of the schema to query - */ - schema(schema) { - return this.rest.schema(schema); - } - /** - * Perform a function call. - * - * @param fn - The function name to call - * @param args - The arguments to pass to the function call - * @param options - Named parameters - * @param options.head - When set to `true`, `data` will not be returned. - * Useful if you only need the count. - * @param options.count - Count algorithm to use to count rows returned by the - * function. Only applicable for [set-returning - * functions](https://www.postgresql.org/docs/current/functions-srf.html). - * - * `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the - * hood. - * - * `"planned"`: Approximated but fast count algorithm. Uses the Postgres - * statistics under the hood. - * - * `"estimated"`: Uses exact count for low numbers and planned count for high - * numbers. - */ - rpc(fn, args = {}, options) { - return this.rest.rpc(fn, args, options); - } - /** - * Creates a Realtime channel with Broadcast, Presence, and Postgres Changes. - * - * @param {string} name - The name of the Realtime channel. - * @param {Object} opts - The options to pass to the Realtime channel. - * - */ - channel(name, opts = { config: {} }) { - return this.realtime.channel(name, opts); - } - /** - * Returns all Realtime channels. - */ - getChannels() { - return this.realtime.getChannels(); - } - /** - * Unsubscribes and removes Realtime channel from Realtime client. - * - * @param {RealtimeChannel} channel - The name of the Realtime channel. - * - */ - removeChannel(channel) { - return this.realtime.removeChannel(channel); - } - /** - * Unsubscribes and removes all Realtime channels from Realtime client. - */ - removeAllChannels() { - return this.realtime.removeAllChannels(); - } - _getAccessToken() { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - const { data } = yield this.auth.getSession(); - return (_b = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token) !== null && _b !== void 0 ? _b : null; - }); - } - _initSupabaseAuthClient({ autoRefreshToken, persistSession, detectSessionInUrl, storage, storageKey, flowType, debug, }, headers, fetch) { - const authHeaders = { - Authorization: `Bearer ${this.supabaseKey}`, - apikey: `${this.supabaseKey}`, - }; - return new SupabaseAuthClient_1.SupabaseAuthClient({ - url: this.authUrl, - headers: Object.assign(Object.assign({}, authHeaders), headers), - storageKey: storageKey, - autoRefreshToken, - persistSession, - detectSessionInUrl, - storage, - flowType, - debug, - fetch, - }); - } - _initRealtimeClient(options) { - return new realtime_js_1.RealtimeClient(this.realtimeUrl, Object.assign(Object.assign({}, options), { params: Object.assign({ apikey: this.supabaseKey }, options === null || options === void 0 ? void 0 : options.params) })); - } - _listenForAuthEvents() { - let data = this.auth.onAuthStateChange((event, session) => { - this._handleTokenChanged(event, 'CLIENT', session === null || session === void 0 ? void 0 : session.access_token); - }); - return data; - } - _handleTokenChanged(event, source, token) { - if ((event === 'TOKEN_REFRESHED' || event === 'SIGNED_IN') && - this.changedAccessToken !== token) { - // Token has changed - this.realtime.setAuth(token !== null && token !== void 0 ? token : null); - this.changedAccessToken = token; - } - else if (event === 'SIGNED_OUT') { - // Token is removed - this.realtime.setAuth(this.supabaseKey); - if (source == 'STORAGE') - this.auth.signOut(); - this.changedAccessToken = undefined; - } - } -} -exports["default"] = SupabaseClient; -//# sourceMappingURL=SupabaseClient.js.map + function isIdentifierChar(code, astral) { + if (code < 48) { return code === 36 } + if (code < 58) { return true } + if (code < 65) { return false } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) + } -/***/ }), + // ## Token types -/***/ 1206: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + // The assignment of fine-grained, information-carrying type objects + // allows the tokenizer to store the information it has about a + // token in a way that is very cheap for the parser to look up. -"use strict"; + // All token type variables start with an underscore, to make them + // easy to recognize. -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __exportStar = (this && this.__exportStar) || function(m, exports) { - for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.createClient = exports.SupabaseClient = exports.FunctionsError = exports.FunctionsRelayError = exports.FunctionsFetchError = exports.FunctionsHttpError = void 0; -const SupabaseClient_1 = __importDefault(__nccwpck_require__(1807)); -__exportStar(__nccwpck_require__(60), exports); -var functions_js_1 = __nccwpck_require__(8519); -Object.defineProperty(exports, "FunctionsHttpError", ({ enumerable: true, get: function () { return functions_js_1.FunctionsHttpError; } })); -Object.defineProperty(exports, "FunctionsFetchError", ({ enumerable: true, get: function () { return functions_js_1.FunctionsFetchError; } })); -Object.defineProperty(exports, "FunctionsRelayError", ({ enumerable: true, get: function () { return functions_js_1.FunctionsRelayError; } })); -Object.defineProperty(exports, "FunctionsError", ({ enumerable: true, get: function () { return functions_js_1.FunctionsError; } })); -__exportStar(__nccwpck_require__(442), exports); -var SupabaseClient_2 = __nccwpck_require__(1807); -Object.defineProperty(exports, "SupabaseClient", ({ enumerable: true, get: function () { return __importDefault(SupabaseClient_2).default; } })); -/** - * Creates a new Supabase Client. - */ -const createClient = (supabaseUrl, supabaseKey, options) => { - return new SupabaseClient_1.default(supabaseUrl, supabaseKey, options); -}; -exports.createClient = createClient; -//# sourceMappingURL=index.js.map + // The `beforeExpr` property is used to disambiguate between regular + // expressions and divisions. It is set on all token types that can + // be followed by an expression (thus, a slash after them would be a + // regular expression). + // + // The `startsExpr` property is used to check if the token ends a + // `yield` expression. It is set on all token types that either can + // directly start an expression (like a quotation mark) or can + // continue an expression (like the body of a string). + // + // `isLoop` marks a keyword as starting a loop, which is important + // to know when parsing a label, in order to allow or disallow + // continue jumps to that label. -/***/ }), + var TokenType = function TokenType(label, conf) { + if ( conf === void 0 ) conf = {}; -/***/ 7620: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + this.label = label; + this.keyword = conf.keyword; + this.beforeExpr = !!conf.beforeExpr; + this.startsExpr = !!conf.startsExpr; + this.isLoop = !!conf.isLoop; + this.isAssign = !!conf.isAssign; + this.prefix = !!conf.prefix; + this.postfix = !!conf.postfix; + this.binop = conf.binop || null; + this.updateContext = null; + }; -"use strict"; + function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) + } + var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.SupabaseAuthClient = void 0; -const gotrue_js_1 = __nccwpck_require__(60); -class SupabaseAuthClient extends gotrue_js_1.GoTrueClient { - constructor(options) { - super(options); - } -} -exports.SupabaseAuthClient = SupabaseAuthClient; -//# sourceMappingURL=SupabaseAuthClient.js.map + // Map keyword names to token types. -/***/ }), + var keywords = {}; -/***/ 4868: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + // Succinct definitions of keyword token types + function kw(name, options) { + if ( options === void 0 ) options = {}; -"use strict"; + options.keyword = name; + return keywords[name] = new TokenType(name, options) + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.DEFAULT_HEADERS = void 0; -// constants.ts -const version_1 = __nccwpck_require__(6136); -let JS_ENV = ''; -// @ts-ignore -if (typeof Deno !== 'undefined') { - JS_ENV = 'deno'; -} -else if (typeof document !== 'undefined') { - JS_ENV = 'web'; -} -else if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') { - JS_ENV = 'react-native'; -} -else { - JS_ENV = 'node'; -} -exports.DEFAULT_HEADERS = { 'X-Client-Info': `supabase-js-${JS_ENV}/${version_1.version}` }; -//# sourceMappingURL=constants.js.map + var types$1 = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + privateId: new TokenType("privateId", startsExpr), + eof: new TokenType("eof"), -/***/ }), + // Punctuation token types. + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + questionDot: new TokenType("?."), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + invalidTemplate: new TokenType("invalidTemplate"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), -/***/ 785: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. -"use strict"; + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=/===/!==", 6), + relational: binop("/<=/>=", 7), + bitShift: binop("<>/>>>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), + coalesce: binop("??", 1), -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.fetchWithAuth = exports.resolveHeadersConstructor = exports.resolveFetch = void 0; -// @ts-ignore -const node_fetch_1 = __importStar(__nccwpck_require__(2668)); -const resolveFetch = (customFetch) => { - let _fetch; - if (customFetch) { - _fetch = customFetch; - } - else if (typeof fetch === 'undefined') { - _fetch = node_fetch_1.default; - } - else { - _fetch = fetch; - } - return (...args) => _fetch(...args); -}; -exports.resolveFetch = resolveFetch; -const resolveHeadersConstructor = () => { - if (typeof Headers === 'undefined') { - return node_fetch_1.Headers; - } - return Headers; -}; -exports.resolveHeadersConstructor = resolveHeadersConstructor; -const fetchWithAuth = (supabaseKey, getAccessToken, customFetch) => { - const fetch = (0, exports.resolveFetch)(customFetch); - const HeadersConstructor = (0, exports.resolveHeadersConstructor)(); - return (input, init) => __awaiter(void 0, void 0, void 0, function* () { - var _a; - const accessToken = (_a = (yield getAccessToken())) !== null && _a !== void 0 ? _a : supabaseKey; - let headers = new HeadersConstructor(init === null || init === void 0 ? void 0 : init.headers); - if (!headers.has('apikey')) { - headers.set('apikey', supabaseKey); - } - if (!headers.has('Authorization')) { - headers.set('Authorization', `Bearer ${accessToken}`); - } - return fetch(input, Object.assign(Object.assign({}, init), { headers })); - }); -}; -exports.fetchWithAuth = fetchWithAuth; -//# sourceMappingURL=fetch.js.map + // Keyword token types. + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class", startsExpr), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import", startsExpr), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) + }; -/***/ }), + // Matches a whole line break (where CRLF is considered a single + // line break). Used to count lines. -/***/ 3575: -/***/ ((__unused_webpack_module, exports) => { + var lineBreak = /\r\n?|\n|\u2028|\u2029/; + var lineBreakG = new RegExp(lineBreak.source, "g"); -"use strict"; + function isNewLine(code) { + return code === 10 || code === 13 || code === 0x2028 || code === 0x2029 + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.applySettingDefaults = exports.isBrowser = exports.stripTrailingSlash = exports.uuid = void 0; -function uuid() { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8; - return v.toString(16); - }); -} -exports.uuid = uuid; -function stripTrailingSlash(url) { - return url.replace(/\/$/, ''); -} -exports.stripTrailingSlash = stripTrailingSlash; -const isBrowser = () => typeof window !== 'undefined'; -exports.isBrowser = isBrowser; -function applySettingDefaults(options, defaults) { - const { db: dbOptions, auth: authOptions, realtime: realtimeOptions, global: globalOptions, } = options; - const { db: DEFAULT_DB_OPTIONS, auth: DEFAULT_AUTH_OPTIONS, realtime: DEFAULT_REALTIME_OPTIONS, global: DEFAULT_GLOBAL_OPTIONS, } = defaults; - return { - db: Object.assign(Object.assign({}, DEFAULT_DB_OPTIONS), dbOptions), - auth: Object.assign(Object.assign({}, DEFAULT_AUTH_OPTIONS), authOptions), - realtime: Object.assign(Object.assign({}, DEFAULT_REALTIME_OPTIONS), realtimeOptions), - global: Object.assign(Object.assign({}, DEFAULT_GLOBAL_OPTIONS), globalOptions), - }; -} -exports.applySettingDefaults = applySettingDefaults; -//# sourceMappingURL=helpers.js.map + function nextLineBreak(code, from, end) { + if ( end === void 0 ) end = code.length; -/***/ }), + for (var i = from; i < end; i++) { + var next = code.charCodeAt(i); + if (isNewLine(next)) + { return i < end - 1 && next === 13 && code.charCodeAt(i + 1) === 10 ? i + 2 : i + 1 } + } + return -1 + } -/***/ 6136: -/***/ ((__unused_webpack_module, exports) => { + var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/; -"use strict"; + var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.version = void 0; -exports.version = '2.38.4'; -//# sourceMappingURL=version.js.map + var ref = Object.prototype; + var hasOwnProperty = ref.hasOwnProperty; + var toString = ref.toString; -/***/ }), + var hasOwn = Object.hasOwn || (function (obj, propName) { return ( + hasOwnProperty.call(obj, propName) + ); }); -/***/ 4243: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var isArray = Array.isArray || (function (obj) { return ( + toString.call(obj) === "[object Array]" + ); }); -"use strict"; + function wordsRegexp(words) { + return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$") + } + function codePointToString(code) { + // UTF-16 Decoding + if (code <= 0xFFFF) { return String.fromCharCode(code) } + code -= 0x10000; + return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00) + } -const XHTMLEntities = __nccwpck_require__(3096); + var loneSurrogate = /(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/; -const hexNumber = /^[\da-fA-F]+$/; -const decimalNumber = /^\d+$/; + // These are used when `options.locations` is on, for the + // `startLoc` and `endLoc` properties. -// The map to `acorn-jsx` tokens from `acorn` namespace objects. -const acornJsxMap = new WeakMap(); + var Position = function Position(line, col) { + this.line = line; + this.column = col; + }; -// Get the original tokens for the given `acorn` namespace object. -function getJsxTokens(acorn) { - acorn = acorn.Parser.acorn || acorn; - let acornJsx = acornJsxMap.get(acorn); - if (!acornJsx) { - const tt = acorn.tokTypes; - const TokContext = acorn.TokContext; - const TokenType = acorn.TokenType; - const tc_oTag = new TokContext('...', true, true); - const tokContexts = { - tc_oTag: tc_oTag, - tc_cTag: tc_cTag, - tc_expr: tc_expr - }; - const tokTypes = { - jsxName: new TokenType('jsxName'), - jsxText: new TokenType('jsxText', {beforeExpr: true}), - jsxTagStart: new TokenType('jsxTagStart', {startsExpr: true}), - jsxTagEnd: new TokenType('jsxTagEnd') - }; + Position.prototype.offset = function offset (n) { + return new Position(this.line, this.column + n) + }; - tokTypes.jsxTagStart.updateContext = function() { - this.context.push(tc_expr); // treat as beginning of JSX expression - this.context.push(tc_oTag); // start opening tag context - this.exprAllowed = false; - }; - tokTypes.jsxTagEnd.updateContext = function(prevType) { - let out = this.context.pop(); - if (out === tc_oTag && prevType === tt.slash || out === tc_cTag) { - this.context.pop(); - this.exprAllowed = this.curContext() === tc_expr; - } else { - this.exprAllowed = true; - } - }; + var SourceLocation = function SourceLocation(p, start, end) { + this.start = start; + this.end = end; + if (p.sourceFile !== null) { this.source = p.sourceFile; } + }; - acornJsx = { tokContexts: tokContexts, tokTypes: tokTypes }; - acornJsxMap.set(acorn, acornJsx); + // The `getLineInfo` function is mostly useful when the + // `locations` option is off (for performance reasons) and you + // want to find the line/column position for a given character + // offset. `input` should be the code string that the offset refers + // into. + + function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + var nextBreak = nextLineBreak(input, cur, offset); + if (nextBreak < 0) { return new Position(line, offset - cur) } + ++line; + cur = nextBreak; + } } - return acornJsx; -} + // A second argument must be given to configure the parser process. + // These options are recognized (only `ecmaVersion` is required): -// Transforms JSX element name to string. + var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must be + // either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 + // (2019), 11 (2020), 12 (2021), 13 (2022), 14 (2023), or `"latest"` + // (the latest version the library supports). This influences + // support for strict mode, the set of reserved words, and support + // for new syntax features. + ecmaVersion: null, + // `sourceType` indicates the mode the code should be parsed in. + // Can be either `"script"` or `"module"`. This influences global + // strict mode and parsing of `import` and `export` declarations. + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called + // when a semicolon is automatically inserted. It will be passed + // the position of the comma as an offset, and if `locations` is + // enabled, it is given the location as a `{line, column}` object + // as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program, and an import.meta expression + // in a script isn't considered an error. + allowImportExportEverywhere: false, + // By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022. + // When enabled, await identifiers are allowed to appear at the top-level scope, + // but they are still not allowed in non-async functions. + allowAwaitOutsideFunction: null, + // When enabled, super identifiers are not constrained to + // appearing in methods and do not raise an error when they appear elsewhere. + allowSuperOutsideMethod: null, + // When enabled, hashbang directive in the beginning of file is + // allowed and treated as a line comment. Enabled by default when + // `ecmaVersion` >= 2023. + allowHashBang: false, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false + }; -function getQualifiedJSXName(object) { - if (!object) - return object; + // Interpret and default an options object - if (object.type === 'JSXIdentifier') - return object.name; + var warnedAboutEcmaVersion = false; - if (object.type === 'JSXNamespacedName') - return object.namespace.name + ':' + object.name.name; + function getOptions(opts) { + var options = {}; - if (object.type === 'JSXMemberExpression') - return getQualifiedJSXName(object.object) + '.' + - getQualifiedJSXName(object.property); -} + for (var opt in defaultOptions) + { options[opt] = opts && hasOwn(opts, opt) ? opts[opt] : defaultOptions[opt]; } -module.exports = function(options) { - options = options || {}; - return function(Parser) { - return plugin({ - allowNamespaces: options.allowNamespaces !== false, - allowNamespacedObjects: !!options.allowNamespacedObjects - }, Parser); - }; -}; + if (options.ecmaVersion === "latest") { + options.ecmaVersion = 1e8; + } else if (options.ecmaVersion == null) { + if (!warnedAboutEcmaVersion && typeof console === "object" && console.warn) { + warnedAboutEcmaVersion = true; + console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future."); + } + options.ecmaVersion = 11; + } else if (options.ecmaVersion >= 2015) { + options.ecmaVersion -= 2009; + } -// This is `tokTypes` of the peer dep. -// This can be different instances from the actual `tokTypes` this plugin uses. -Object.defineProperty(module.exports, "tokTypes", ({ - get: function get_tokTypes() { - return getJsxTokens(__nccwpck_require__(390)).tokTypes; - }, - configurable: true, - enumerable: true -})); + if (options.allowReserved == null) + { options.allowReserved = options.ecmaVersion < 5; } -function plugin(options, Parser) { - const acorn = Parser.acorn || __nccwpck_require__(390); - const acornJsx = getJsxTokens(acorn); - const tt = acorn.tokTypes; - const tok = acornJsx.tokTypes; - const tokContexts = acorn.tokContexts; - const tc_oTag = acornJsx.tokContexts.tc_oTag; - const tc_cTag = acornJsx.tokContexts.tc_cTag; - const tc_expr = acornJsx.tokContexts.tc_expr; - const isNewLine = acorn.isNewLine; - const isIdentifierStart = acorn.isIdentifierStart; - const isIdentifierChar = acorn.isIdentifierChar; + if (!opts || opts.allowHashBang == null) + { options.allowHashBang = options.ecmaVersion >= 14; } - return class extends Parser { - // Expose actual `tokTypes` and `tokContexts` to other plugins. - static get acornJsx() { - return acornJsx; + if (isArray(options.onToken)) { + var tokens = options.onToken; + options.onToken = function (token) { return tokens.push(token); }; } + if (isArray(options.onComment)) + { options.onComment = pushComment(options, options.onComment); } - // Reads inline JSX contents token. - jsx_readToken() { - let out = '', chunkStart = this.pos; - for (;;) { - if (this.pos >= this.input.length) - this.raise(this.start, 'Unterminated JSX contents'); - let ch = this.input.charCodeAt(this.pos); + return options + } - switch (ch) { - case 60: // '<' - case 123: // '{' - if (this.pos === this.start) { - if (ch === 60 && this.exprAllowed) { - ++this.pos; - return this.finishToken(tok.jsxTagStart); - } - return this.getTokenFromCode(ch); - } - out += this.input.slice(chunkStart, this.pos); - return this.finishToken(tok.jsxText, out); + function pushComment(options, array) { + return function(block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? "Block" : "Line", + value: text, + start: start, + end: end + }; + if (options.locations) + { comment.loc = new SourceLocation(this, startLoc, endLoc); } + if (options.ranges) + { comment.range = [start, end]; } + array.push(comment); + } + } - case 38: // '&' - out += this.input.slice(chunkStart, this.pos); - out += this.jsx_readEntity(); - chunkStart = this.pos; - break; + // Each scope gets a bitset that may contain these flags + var + SCOPE_TOP = 1, + SCOPE_FUNCTION = 2, + SCOPE_ASYNC = 4, + SCOPE_GENERATOR = 8, + SCOPE_ARROW = 16, + SCOPE_SIMPLE_CATCH = 32, + SCOPE_SUPER = 64, + SCOPE_DIRECT_SUPER = 128, + SCOPE_CLASS_STATIC_BLOCK = 256, + SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK; - case 62: // '>' - case 125: // '}' - this.raise( - this.pos, - "Unexpected token `" + this.input[this.pos] + "`. Did you mean `" + - (ch === 62 ? ">" : "}") + "` or " + "`{\"" + this.input[this.pos] + "\"}" + "`?" - ); + function functionFlags(async, generator) { + return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0) + } - default: - if (isNewLine(ch)) { - out += this.input.slice(chunkStart, this.pos); - out += this.jsx_readNewLine(true); - chunkStart = this.pos; - } else { - ++this.pos; - } - } - } + // Used in checkLVal* and declareName to determine the type of a binding + var + BIND_NONE = 0, // Not a binding + BIND_VAR = 1, // Var-style binding + BIND_LEXICAL = 2, // Let- or const-style binding + BIND_FUNCTION = 3, // Function declaration + BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding + BIND_OUTSIDE = 5; // Special case for function names as bound inside the function + + var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options); + this.sourceFile = options.sourceFile; + this.keywords = wordsRegexp(keywords$1[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]); + var reserved = ""; + if (options.allowReserved !== true) { + reserved = reservedWords[options.ecmaVersion >= 6 ? 6 : options.ecmaVersion === 5 ? 5 : 3]; + if (options.sourceType === "module") { reserved += " await"; } } + this.reservedWords = wordsRegexp(reserved); + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; + this.reservedWordsStrict = wordsRegexp(reservedStrict); + this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind); + this.input = String(input); - jsx_readNewLine(normalizeCRLF) { - let ch = this.input.charCodeAt(this.pos); - let out; - ++this.pos; - if (ch === 13 && this.input.charCodeAt(this.pos) === 10) { - ++this.pos; - out = normalizeCRLF ? '\n' : '\r\n'; - } else { - out = String.fromCharCode(ch); - } - if (this.options.locations) { - ++this.curLine; - this.lineStart = this.pos; - } + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false; - return out; - } + // Set up token state - jsx_readString(quote) { - let out = '', chunkStart = ++this.pos; - for (;;) { - if (this.pos >= this.input.length) - this.raise(this.start, 'Unterminated string constant'); - let ch = this.input.charCodeAt(this.pos); - if (ch === quote) break; - if (ch === 38) { // '&' - out += this.input.slice(chunkStart, this.pos); - out += this.jsx_readEntity(); - chunkStart = this.pos; - } else if (isNewLine(ch)) { - out += this.input.slice(chunkStart, this.pos); - out += this.jsx_readNewLine(false); - chunkStart = this.pos; - } else { - ++this.pos; - } - } - out += this.input.slice(chunkStart, this.pos++); - return this.finishToken(tt.string, out); + // The current position of the tokenizer in the input. + if (startPos) { + this.pos = startPos; + this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1; + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; + } else { + this.pos = this.lineStart = 0; + this.curLine = 1; } - jsx_readEntity() { - let str = '', count = 0, entity; - let ch = this.input[this.pos]; - if (ch !== '&') - this.raise(this.pos, 'Entity must start with an ampersand'); - let startPos = ++this.pos; - while (this.pos < this.input.length && count++ < 10) { - ch = this.input[this.pos++]; - if (ch === ';') { - if (str[0] === '#') { - if (str[1] === 'x') { - str = str.substr(2); - if (hexNumber.test(str)) - entity = String.fromCharCode(parseInt(str, 16)); - } else { - str = str.substr(1); - if (decimalNumber.test(str)) - entity = String.fromCharCode(parseInt(str, 10)); - } - } else { - entity = XHTMLEntities[str]; - } - break; - } - str += ch; - } - if (!entity) { - this.pos = startPos; - return '&'; - } - return entity; - } + // Properties of the current token: + // Its type + this.type = types$1.eof; + // For tokens that include more information than their type, the value + this.value = null; + // Its start and end offset + this.start = this.end = this.pos; + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition(); - // Read a JSX identifier (valid tag or attribute name). - // - // Optimized version since JSX identifiers can't contain - // escape characters and so can be read as single slice. - // Also assumes that first character was already checked - // by isIdentifierStart in readToken. + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null; + this.lastTokStart = this.lastTokEnd = this.pos; - jsx_readWord() { - let ch, start = this.pos; - do { - ch = this.input.charCodeAt(++this.pos); - } while (isIdentifierChar(ch) || ch === 45); // '-' - return this.finishToken(tok.jsxName, this.input.slice(start, this.pos)); - } + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext(); + this.exprAllowed = true; - // Parse next token as JSX identifier + // Figure out if it's a module code. + this.inModule = options.sourceType === "module"; + this.strict = this.inModule || this.strictDirective(this.pos); - jsx_parseIdentifier() { - let node = this.startNode(); - if (this.type === tok.jsxName) - node.name = this.value; - else if (this.type.keyword) - node.name = this.type.keyword; - else - this.unexpected(); - this.next(); - return this.finishNode(node, 'JSXIdentifier'); - } + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1; + this.potentialArrowInForAwait = false; - // Parse namespaced identifier. + // Positions to delayed-check that yield/await does not exist in default parameters. + this.yieldPos = this.awaitPos = this.awaitIdentPos = 0; + // Labels in scope. + this.labels = []; + // Thus-far undefined exports. + this.undefinedExports = Object.create(null); - jsx_parseNamespacedName() { - let startPos = this.start, startLoc = this.startLoc; - let name = this.jsx_parseIdentifier(); - if (!options.allowNamespaces || !this.eat(tt.colon)) return name; - var node = this.startNodeAt(startPos, startLoc); - node.namespace = name; - node.name = this.jsx_parseIdentifier(); - return this.finishNode(node, 'JSXNamespacedName'); - } + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") + { this.skipLineComment(2); } - // Parses element name in any form - namespaced, member - // or single identifier. + // Scope tracking for duplicate variable names (see scope.js) + this.scopeStack = []; + this.enterScope(SCOPE_TOP); - jsx_parseElementName() { - if (this.type === tok.jsxTagEnd) return ''; - let startPos = this.start, startLoc = this.startLoc; - let node = this.jsx_parseNamespacedName(); - if (this.type === tt.dot && node.type === 'JSXNamespacedName' && !options.allowNamespacedObjects) { - this.unexpected(); - } - while (this.eat(tt.dot)) { - let newNode = this.startNodeAt(startPos, startLoc); - newNode.object = node; - newNode.property = this.jsx_parseIdentifier(); - node = this.finishNode(newNode, 'JSXMemberExpression'); - } - return node; - } + // For RegExp validation + this.regexpState = null; - // Parses any type of JSX attribute value. + // The stack of private names. + // Each element has two properties: 'declared' and 'used'. + // When it exited from the outermost class definition, all used private names must be declared. + this.privateNameStack = []; + }; - jsx_parseAttributeValue() { - switch (this.type) { - case tt.braceL: - let node = this.jsx_parseExpressionContainer(); - if (node.expression.type === 'JSXEmptyExpression') - this.raise(node.start, 'JSX attributes must only be assigned a non-empty expression'); - return node; + var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },allowNewDotTarget: { configurable: true },inClassStaticBlock: { configurable: true } }; - case tok.jsxTagStart: - case tt.string: - return this.parseExprAtom(); + Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode(); + this.nextToken(); + return this.parseTopLevel(node) + }; - default: - this.raise(this.start, 'JSX value should be either an expression or a quoted JSX text'); - } - } + prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 }; - // JSXEmptyExpression is unique type since it doesn't actually parse anything, - // and so it should start at the end of last read token (left brace) and finish - // at the beginning of the next one (right brace). + prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 && !this.currentVarScope().inClassFieldInit }; - jsx_parseEmptyExpression() { - let node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc); - return this.finishNodeAt(node, 'JSXEmptyExpression', this.start, this.startLoc); + prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 && !this.currentVarScope().inClassFieldInit }; + + prototypeAccessors.canAwait.get = function () { + for (var i = this.scopeStack.length - 1; i >= 0; i--) { + var scope = this.scopeStack[i]; + if (scope.inClassFieldInit || scope.flags & SCOPE_CLASS_STATIC_BLOCK) { return false } + if (scope.flags & SCOPE_FUNCTION) { return (scope.flags & SCOPE_ASYNC) > 0 } } + return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction + }; - // Parses JSX expression enclosed into curly brackets. + prototypeAccessors.allowSuper.get = function () { + var ref = this.currentThisScope(); + var flags = ref.flags; + var inClassFieldInit = ref.inClassFieldInit; + return (flags & SCOPE_SUPER) > 0 || inClassFieldInit || this.options.allowSuperOutsideMethod + }; - jsx_parseExpressionContainer() { - let node = this.startNode(); - this.next(); - node.expression = this.type === tt.braceR - ? this.jsx_parseEmptyExpression() - : this.parseExpression(); - this.expect(tt.braceR); - return this.finishNode(node, 'JSXExpressionContainer'); - } + prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 }; - // Parses following JSX attribute name-value pair. + prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) }; - jsx_parseAttribute() { - let node = this.startNode(); - if (this.eat(tt.braceL)) { - this.expect(tt.ellipsis); - node.argument = this.parseMaybeAssign(); - this.expect(tt.braceR); - return this.finishNode(node, 'JSXSpreadAttribute'); + prototypeAccessors.allowNewDotTarget.get = function () { + var ref = this.currentThisScope(); + var flags = ref.flags; + var inClassFieldInit = ref.inClassFieldInit; + return (flags & (SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK)) > 0 || inClassFieldInit + }; + + prototypeAccessors.inClassStaticBlock.get = function () { + return (this.currentVarScope().flags & SCOPE_CLASS_STATIC_BLOCK) > 0 + }; + + Parser.extend = function extend () { + var plugins = [], len = arguments.length; + while ( len-- ) plugins[ len ] = arguments[ len ]; + + var cls = this; + for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); } + return cls + }; + + Parser.parse = function parse (input, options) { + return new this(options, input).parse() + }; + + Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) { + var parser = new this(options, input, pos); + parser.nextToken(); + return parser.parseExpression() + }; + + Parser.tokenizer = function tokenizer (input, options) { + return new this(options, input) + }; + + Object.defineProperties( Parser.prototype, prototypeAccessors ); + + var pp$9 = Parser.prototype; + + // ## Parser utilities + + var literal = /^(?:'((?:\\.|[^'\\])*?)'|"((?:\\.|[^"\\])*?)")/; + pp$9.strictDirective = function(start) { + if (this.options.ecmaVersion < 5) { return false } + for (;;) { + // Try to find string literal. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + var match = literal.exec(this.input.slice(start)); + if (!match) { return false } + if ((match[1] || match[2]) === "use strict") { + skipWhiteSpace.lastIndex = start + match[0].length; + var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length; + var next = this.input.charAt(end); + return next === ";" || next === "}" || + (lineBreak.test(spaceAfter[0]) && + !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "=")) } - node.name = this.jsx_parseNamespacedName(); - node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null; - return this.finishNode(node, 'JSXAttribute'); + start += match[0].length; + + // Skip semicolon, if any. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + if (this.input[start] === ";") + { start++; } } + }; - // Parses JSX opening tag starting after '<'. + // Predicate that tests whether the next token is of the given + // type, and if yes, consumes it as a side effect. - jsx_parseOpeningElementAt(startPos, startLoc) { - let node = this.startNodeAt(startPos, startLoc); - node.attributes = []; - let nodeName = this.jsx_parseElementName(); - if (nodeName) node.name = nodeName; - while (this.type !== tt.slash && this.type !== tok.jsxTagEnd) - node.attributes.push(this.jsx_parseAttribute()); - node.selfClosing = this.eat(tt.slash); - this.expect(tok.jsxTagEnd); - return this.finishNode(node, nodeName ? 'JSXOpeningElement' : 'JSXOpeningFragment'); + pp$9.eat = function(type) { + if (this.type === type) { + this.next(); + return true + } else { + return false } + }; - // Parses JSX closing tag starting after ''); - } - } - let fragmentOrElement = openingElement.name ? 'Element' : 'Fragment'; + pp$9.canInsertSemicolon = function() { + return this.type === types$1.eof || + this.type === types$1.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + }; - node['opening' + fragmentOrElement] = openingElement; - node['closing' + fragmentOrElement] = closingElement; - node.children = children; - if (this.type === tt.relational && this.value === "<") { - this.raise(this.start, "Adjacent JSX elements must be wrapped in an enclosing tag"); - } - return this.finishNode(node, 'JSX' + fragmentOrElement); + pp$9.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); } + return true } + }; - // Parse JSX text + // Consume a semicolon, or, failing that, see if we are allowed to + // pretend that there is a semicolon at this position. - jsx_parseText() { - let node = this.parseLiteral(this.value); - node.type = "JSXText"; - return node; + pp$9.semicolon = function() { + if (!this.eat(types$1.semi) && !this.insertSemicolon()) { this.unexpected(); } + }; + + pp$9.afterTrailingComma = function(tokType, notNext) { + if (this.type === tokType) { + if (this.options.onTrailingComma) + { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); } + if (!notNext) + { this.next(); } + return true } + }; - // Parses entire JSX element from current position. + // Expect a token of a given type. If found, consume it, otherwise, + // raise an unexpected token error. - jsx_parseElement() { - let startPos = this.start, startLoc = this.startLoc; - this.next(); - return this.jsx_parseElementAt(startPos, startLoc); + pp$9.expect = function(type) { + this.eat(type) || this.unexpected(); + }; + + // Raise an unexpected token error. + + pp$9.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token"); + }; + + var DestructuringErrors = function DestructuringErrors() { + this.shorthandAssign = + this.trailingComma = + this.parenthesizedAssign = + this.parenthesizedBind = + this.doubleProto = + -1; + }; + + pp$9.checkPatternErrors = function(refDestructuringErrors, isAssign) { + if (!refDestructuringErrors) { return } + if (refDestructuringErrors.trailingComma > -1) + { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); } + var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind; + if (parens > -1) { this.raiseRecoverable(parens, isAssign ? "Assigning to rvalue" : "Parenthesized pattern"); } + }; + + pp$9.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + if (!refDestructuringErrors) { return false } + var shorthandAssign = refDestructuringErrors.shorthandAssign; + var doubleProto = refDestructuringErrors.doubleProto; + if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 } + if (shorthandAssign >= 0) + { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); } + if (doubleProto >= 0) + { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); } + }; + + pp$9.checkYieldAwaitInDefaultParams = function() { + if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) + { this.raise(this.yieldPos, "Yield expression cannot be a default value"); } + if (this.awaitPos) + { this.raise(this.awaitPos, "Await expression cannot be a default value"); } + }; + + pp$9.isSimpleAssignTarget = function(expr) { + if (expr.type === "ParenthesizedExpression") + { return this.isSimpleAssignTarget(expr.expression) } + return expr.type === "Identifier" || expr.type === "MemberExpression" + }; + + var pp$8 = Parser.prototype; + + // ### Statement parsing + + // Parse a program. Initializes the parser, reads any number of + // statements, and wraps them in a Program node. Optionally takes a + // `program` argument. If present, the statements will be appended + // to its body instead of creating a new node. + + pp$8.parseTopLevel = function(node) { + var exports = Object.create(null); + if (!node.body) { node.body = []; } + while (this.type !== types$1.eof) { + var stmt = this.parseStatement(null, true, exports); + node.body.push(stmt); } + if (this.inModule) + { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1) + { + var name = list[i]; - parseExprAtom(refShortHandDefaultPos) { - if (this.type === tok.jsxText) - return this.jsx_parseText(); - else if (this.type === tok.jsxTagStart) - return this.jsx_parseElement(); - else - return super.parseExprAtom(refShortHandDefaultPos); + this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined")); + } } + this.adaptDirectivePrologue(node.body); + this.next(); + node.sourceType = this.options.sourceType; + return this.finishNode(node, "Program") + }; + + var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; + + pp$8.isLet = function(context) { + if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false } + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); + // For ambiguous cases, determine if a LexicalDeclaration (or only a + // Statement) is allowed here. If context is not empty then only a Statement + // is allowed. However, `let [` is an explicit negative lookahead for + // ExpressionStatement, so special-case it first. + if (nextCh === 91 || nextCh === 92) { return true } // '[', '/' + if (context) { return false } + + if (nextCh === 123 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '{', astral + if (isIdentifierStart(nextCh, true)) { + var pos = next + 1; + while (isIdentifierChar(nextCh = this.input.charCodeAt(pos), true)) { ++pos; } + if (nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } + var ident = this.input.slice(next, pos); + if (!keywordRelationalOperator.test(ident)) { return true } } + return false + }; - readToken(code) { - let context = this.curContext(); + // check 'async [no LineTerminator here] function' + // - 'async /*foo*/ function' is OK. + // - 'async /*\n*/ function' is invalid. + pp$8.isAsyncFunction = function() { + if (this.options.ecmaVersion < 8 || !this.isContextual("async")) + { return false } - if (context === tc_expr) return this.jsx_readToken(); + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, after; + return !lineBreak.test(this.input.slice(this.pos, next)) && + this.input.slice(next, next + 8) === "function" && + (next + 8 === this.input.length || + !(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00)) + }; - if (context === tc_oTag || context === tc_cTag) { - if (isIdentifierStart(code)) return this.jsx_readWord(); + // Parse a single statement. + // + // If expecting a statement and finding a slash operator, parse a + // regular expression literal. This is to handle cases like + // `if (foo) /blah/.exec(foo)`, where looking at the previous token + // does not help. - if (code == 62) { - ++this.pos; - return this.finishToken(tok.jsxTagEnd); - } + pp$8.parseStatement = function(context, topLevel, exports) { + var starttype = this.type, node = this.startNode(), kind; - if ((code === 34 || code === 39) && context == tc_oTag) - return this.jsx_readString(code); + if (this.isLet(context)) { + starttype = types$1._var; + kind = "let"; + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + switch (starttype) { + case types$1._break: case types$1._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case types$1._debugger: return this.parseDebuggerStatement(node) + case types$1._do: return this.parseDoStatement(node) + case types$1._for: return this.parseForStatement(node) + case types$1._function: + // Function as sole body of either an if statement or a labeled statement + // works, but not when it is part of a labeled statement that is the sole + // body of an if statement. + if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); } + return this.parseFunctionStatement(node, false, !context) + case types$1._class: + if (context) { this.unexpected(); } + return this.parseClass(node, true) + case types$1._if: return this.parseIfStatement(node) + case types$1._return: return this.parseReturnStatement(node) + case types$1._switch: return this.parseSwitchStatement(node) + case types$1._throw: return this.parseThrowStatement(node) + case types$1._try: return this.parseTryStatement(node) + case types$1._const: case types$1._var: + kind = kind || this.value; + if (context && kind !== "var") { this.unexpected(); } + return this.parseVarStatement(node, kind) + case types$1._while: return this.parseWhileStatement(node) + case types$1._with: return this.parseWithStatement(node) + case types$1.braceL: return this.parseBlock(true, node) + case types$1.semi: return this.parseEmptyStatement(node) + case types$1._export: + case types$1._import: + if (this.options.ecmaVersion > 10 && starttype === types$1._import) { + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); + if (nextCh === 40 || nextCh === 46) // '(' or '.' + { return this.parseExpressionStatement(node, this.parseExpression()) } } - if (code === 60 && this.exprAllowed && this.input.charCodeAt(this.pos + 1) !== 33) { - ++this.pos; - return this.finishToken(tok.jsxTagStart); + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + { this.raise(this.start, "'import' and 'export' may only appear at the top level"); } + if (!this.inModule) + { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); } } - return super.readToken(code); + return starttype === types$1._import ? this.parseImport(node) : this.parseExport(node, exports) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + if (this.isAsyncFunction()) { + if (context) { this.unexpected(); } + this.next(); + return this.parseFunctionStatement(node, true, !context) + } + + var maybeName = this.value, expr = this.parseExpression(); + if (starttype === types$1.name && expr.type === "Identifier" && this.eat(types$1.colon)) + { return this.parseLabeledStatement(node, maybeName, expr, context) } + else { return this.parseExpressionStatement(node, expr) } } + }; - updateContext(prevType) { - if (this.type == tt.braceL) { - var curContext = this.curContext(); - if (curContext == tc_oTag) this.context.push(tokContexts.b_expr); - else if (curContext == tc_expr) this.context.push(tokContexts.b_tmpl); - else super.updateContext(prevType); - this.exprAllowed = true; - } else if (this.type === tt.slash && prevType === tok.jsxTagStart) { - this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore - this.context.push(tc_cTag); // reconsider as closing tag context - this.exprAllowed = false; - } else { - return super.updateContext(prevType); + pp$8.parseBreakContinueStatement = function(node, keyword) { + var isBreak = keyword === "break"; + this.next(); + if (this.eat(types$1.semi) || this.insertSemicolon()) { node.label = null; } + else if (this.type !== types$1.name) { this.unexpected(); } + else { + node.label = this.parseIdent(); + this.semicolon(); + } + + // Verify that there is an actual destination to break or + // continue to. + var i = 0; + for (; i < this.labels.length; ++i) { + var lab = this.labels[i]; + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) { break } + if (node.label && isBreak) { break } } } + if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); } + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") }; -} + pp$8.parseDebuggerStatement = function(node) { + this.next(); + this.semicolon(); + return this.finishNode(node, "DebuggerStatement") + }; -/***/ }), + pp$8.parseDoStatement = function(node) { + this.next(); + this.labels.push(loopLabel); + node.body = this.parseStatement("do"); + this.labels.pop(); + this.expect(types$1._while); + node.test = this.parseParenExpression(); + if (this.options.ecmaVersion >= 6) + { this.eat(types$1.semi); } + else + { this.semicolon(); } + return this.finishNode(node, "DoWhileStatement") + }; -/***/ 3096: -/***/ ((module) => { + // Disambiguating between a `for` and a `for`/`in` or `for`/`of` + // loop is non-trivial. Basically, we have to parse the init `var` + // statement or expression, disallowing the `in` operator (see + // the second parameter to `parseExpression`), and then check + // whether the next token is `in` or `of`. When there is no init + // part (semicolon immediately after the opening parenthesis), it + // is a regular `for` loop. -module.exports = { - quot: '\u0022', - amp: '&', - apos: '\u0027', - lt: '<', - gt: '>', - nbsp: '\u00A0', - iexcl: '\u00A1', - cent: '\u00A2', - pound: '\u00A3', - curren: '\u00A4', - yen: '\u00A5', - brvbar: '\u00A6', - sect: '\u00A7', - uml: '\u00A8', - copy: '\u00A9', - ordf: '\u00AA', - laquo: '\u00AB', - not: '\u00AC', - shy: '\u00AD', - reg: '\u00AE', - macr: '\u00AF', - deg: '\u00B0', - plusmn: '\u00B1', - sup2: '\u00B2', - sup3: '\u00B3', - acute: '\u00B4', - micro: '\u00B5', - para: '\u00B6', - middot: '\u00B7', - cedil: '\u00B8', - sup1: '\u00B9', - ordm: '\u00BA', - raquo: '\u00BB', - frac14: '\u00BC', - frac12: '\u00BD', - frac34: '\u00BE', - iquest: '\u00BF', - Agrave: '\u00C0', - Aacute: '\u00C1', - Acirc: '\u00C2', - Atilde: '\u00C3', - Auml: '\u00C4', - Aring: '\u00C5', - AElig: '\u00C6', - Ccedil: '\u00C7', - Egrave: '\u00C8', - Eacute: '\u00C9', - Ecirc: '\u00CA', - Euml: '\u00CB', - Igrave: '\u00CC', - Iacute: '\u00CD', - Icirc: '\u00CE', - Iuml: '\u00CF', - ETH: '\u00D0', - Ntilde: '\u00D1', - Ograve: '\u00D2', - Oacute: '\u00D3', - Ocirc: '\u00D4', - Otilde: '\u00D5', - Ouml: '\u00D6', - times: '\u00D7', - Oslash: '\u00D8', - Ugrave: '\u00D9', - Uacute: '\u00DA', - Ucirc: '\u00DB', - Uuml: '\u00DC', - Yacute: '\u00DD', - THORN: '\u00DE', - szlig: '\u00DF', - agrave: '\u00E0', - aacute: '\u00E1', - acirc: '\u00E2', - atilde: '\u00E3', - auml: '\u00E4', - aring: '\u00E5', - aelig: '\u00E6', - ccedil: '\u00E7', - egrave: '\u00E8', - eacute: '\u00E9', - ecirc: '\u00EA', - euml: '\u00EB', - igrave: '\u00EC', - iacute: '\u00ED', - icirc: '\u00EE', - iuml: '\u00EF', - eth: '\u00F0', - ntilde: '\u00F1', - ograve: '\u00F2', - oacute: '\u00F3', - ocirc: '\u00F4', - otilde: '\u00F5', - ouml: '\u00F6', - divide: '\u00F7', - oslash: '\u00F8', - ugrave: '\u00F9', - uacute: '\u00FA', - ucirc: '\u00FB', - uuml: '\u00FC', - yacute: '\u00FD', - thorn: '\u00FE', - yuml: '\u00FF', - OElig: '\u0152', - oelig: '\u0153', - Scaron: '\u0160', - scaron: '\u0161', - Yuml: '\u0178', - fnof: '\u0192', - circ: '\u02C6', - tilde: '\u02DC', - Alpha: '\u0391', - Beta: '\u0392', - Gamma: '\u0393', - Delta: '\u0394', - Epsilon: '\u0395', - Zeta: '\u0396', - Eta: '\u0397', - Theta: '\u0398', - Iota: '\u0399', - Kappa: '\u039A', - Lambda: '\u039B', - Mu: '\u039C', - Nu: '\u039D', - Xi: '\u039E', - Omicron: '\u039F', - Pi: '\u03A0', - Rho: '\u03A1', - Sigma: '\u03A3', - Tau: '\u03A4', - Upsilon: '\u03A5', - Phi: '\u03A6', - Chi: '\u03A7', - Psi: '\u03A8', - Omega: '\u03A9', - alpha: '\u03B1', - beta: '\u03B2', - gamma: '\u03B3', - delta: '\u03B4', - epsilon: '\u03B5', - zeta: '\u03B6', - eta: '\u03B7', - theta: '\u03B8', - iota: '\u03B9', - kappa: '\u03BA', - lambda: '\u03BB', - mu: '\u03BC', - nu: '\u03BD', - xi: '\u03BE', - omicron: '\u03BF', - pi: '\u03C0', - rho: '\u03C1', - sigmaf: '\u03C2', - sigma: '\u03C3', - tau: '\u03C4', - upsilon: '\u03C5', - phi: '\u03C6', - chi: '\u03C7', - psi: '\u03C8', - omega: '\u03C9', - thetasym: '\u03D1', - upsih: '\u03D2', - piv: '\u03D6', - ensp: '\u2002', - emsp: '\u2003', - thinsp: '\u2009', - zwnj: '\u200C', - zwj: '\u200D', - lrm: '\u200E', - rlm: '\u200F', - ndash: '\u2013', - mdash: '\u2014', - lsquo: '\u2018', - rsquo: '\u2019', - sbquo: '\u201A', - ldquo: '\u201C', - rdquo: '\u201D', - bdquo: '\u201E', - dagger: '\u2020', - Dagger: '\u2021', - bull: '\u2022', - hellip: '\u2026', - permil: '\u2030', - prime: '\u2032', - Prime: '\u2033', - lsaquo: '\u2039', - rsaquo: '\u203A', - oline: '\u203E', - frasl: '\u2044', - euro: '\u20AC', - image: '\u2111', - weierp: '\u2118', - real: '\u211C', - trade: '\u2122', - alefsym: '\u2135', - larr: '\u2190', - uarr: '\u2191', - rarr: '\u2192', - darr: '\u2193', - harr: '\u2194', - crarr: '\u21B5', - lArr: '\u21D0', - uArr: '\u21D1', - rArr: '\u21D2', - dArr: '\u21D3', - hArr: '\u21D4', - forall: '\u2200', - part: '\u2202', - exist: '\u2203', - empty: '\u2205', - nabla: '\u2207', - isin: '\u2208', - notin: '\u2209', - ni: '\u220B', - prod: '\u220F', - sum: '\u2211', - minus: '\u2212', - lowast: '\u2217', - radic: '\u221A', - prop: '\u221D', - infin: '\u221E', - ang: '\u2220', - and: '\u2227', - or: '\u2228', - cap: '\u2229', - cup: '\u222A', - 'int': '\u222B', - there4: '\u2234', - sim: '\u223C', - cong: '\u2245', - asymp: '\u2248', - ne: '\u2260', - equiv: '\u2261', - le: '\u2264', - ge: '\u2265', - sub: '\u2282', - sup: '\u2283', - nsub: '\u2284', - sube: '\u2286', - supe: '\u2287', - oplus: '\u2295', - otimes: '\u2297', - perp: '\u22A5', - sdot: '\u22C5', - lceil: '\u2308', - rceil: '\u2309', - lfloor: '\u230A', - rfloor: '\u230B', - lang: '\u2329', - rang: '\u232A', - loz: '\u25CA', - spades: '\u2660', - clubs: '\u2663', - hearts: '\u2665', - diams: '\u2666' -}; + pp$8.parseForStatement = function(node) { + this.next(); + var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual("await")) ? this.lastTokStart : -1; + this.labels.push(loopLabel); + this.enterScope(0); + this.expect(types$1.parenL); + if (this.type === types$1.semi) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, null) + } + var isLet = this.isLet(); + if (this.type === types$1._var || this.type === types$1._const || isLet) { + var init$1 = this.startNode(), kind = isLet ? "let" : this.value; + this.next(); + this.parseVar(init$1, true, kind); + this.finishNode(init$1, "VariableDeclaration"); + if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types$1._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } + } + return this.parseForIn(node, init$1) + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init$1) + } + var startsWithLet = this.isContextual("let"), isForOf = false; + var refDestructuringErrors = new DestructuringErrors; + var init = this.parseExpression(awaitAt > -1 ? "await" : true, refDestructuringErrors); + if (this.type === types$1._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types$1._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } + } + if (startsWithLet && isForOf) { this.raise(init.start, "The left-hand side of a for-of loop may not start with 'let'."); } + this.toAssignable(init, false, refDestructuringErrors); + this.checkLValPattern(init); + return this.parseForIn(node, init) + } else { + this.checkExpressionErrors(refDestructuringErrors, true); + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) + }; + pp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) { + this.next(); + return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync) + }; -/***/ }), + pp$8.parseIfStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + // allow function declarations in branches, but only in non-strict mode + node.consequent = this.parseStatement("if"); + node.alternate = this.eat(types$1._else) ? this.parseStatement("if") : null; + return this.finishNode(node, "IfStatement") + }; -/***/ 390: -/***/ (function(__unused_webpack_module, exports) { + pp$8.parseReturnStatement = function(node) { + if (!this.inFunction && !this.options.allowReturnOutsideFunction) + { this.raise(this.start, "'return' outside of function"); } + this.next(); -(function (global, factory) { - true ? factory(exports) : - 0; -})(this, (function (exports) { 'use strict'; + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. - // This file was generated. Do not modify manually! - var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 81, 2, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 9, 5351, 0, 7, 14, 13835, 9, 87, 9, 39, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4706, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 983, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; + if (this.eat(types$1.semi) || this.insertSemicolon()) { node.argument = null; } + else { node.argument = this.parseExpression(); this.semicolon(); } + return this.finishNode(node, "ReturnStatement") + }; - // This file was generated. Do not modify manually! - var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 68, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 4026, 582, 8634, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8936, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 757, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4153, 7, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938, 6, 4191]; + pp$8.parseSwitchStatement = function(node) { + this.next(); + node.discriminant = this.parseParenExpression(); + node.cases = []; + this.expect(types$1.braceL); + this.labels.push(switchLabel); + this.enterScope(0); - // This file was generated. Do not modify manually! - var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0898-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. - // This file was generated. Do not modify manually! - var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ca\ua7d0\ua7d1\ua7d3\ua7d5-\ua7d9\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; + var cur; + for (var sawDefault = false; this.type !== types$1.braceR;) { + if (this.type === types$1._case || this.type === types$1._default) { + var isCase = this.type === types$1._case; + if (cur) { this.finishNode(cur, "SwitchCase"); } + node.cases.push(cur = this.startNode()); + cur.consequent = []; + this.next(); + if (isCase) { + cur.test = this.parseExpression(); + } else { + if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); } + sawDefault = true; + cur.test = null; + } + this.expect(types$1.colon); + } else { + if (!cur) { this.unexpected(); } + cur.consequent.push(this.parseStatement(null)); + } + } + this.exitScope(); + if (cur) { this.finishNode(cur, "SwitchCase"); } + this.next(); // Closing brace + this.labels.pop(); + return this.finishNode(node, "SwitchStatement") + }; - // These are a run-length and offset encoded representation of the + pp$8.parseThrowStatement = function(node) { + this.next(); + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + { this.raise(this.lastTokEnd, "Illegal newline after throw"); } + node.argument = this.parseExpression(); + this.semicolon(); + return this.finishNode(node, "ThrowStatement") + }; - // Reserved word lists for various dialects of the language + // Reused empty array added for node fields that are always empty. - var reservedWords = { - 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", - 5: "class enum extends super const export import", - 6: "enum", - strict: "implements interface let package private protected public static yield", - strictBind: "eval arguments" - }; + var empty$1 = []; - // And the keywords + pp$8.parseTryStatement = function(node) { + this.next(); + node.block = this.parseBlock(); + node.handler = null; + if (this.type === types$1._catch) { + var clause = this.startNode(); + this.next(); + if (this.eat(types$1.parenL)) { + clause.param = this.parseBindingAtom(); + var simple = clause.param.type === "Identifier"; + this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0); + this.checkLValPattern(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL); + this.expect(types$1.parenR); + } else { + if (this.options.ecmaVersion < 10) { this.unexpected(); } + clause.param = null; + this.enterScope(0); + } + clause.body = this.parseBlock(false); + this.exitScope(); + node.handler = this.finishNode(clause, "CatchClause"); + } + node.finalizer = this.eat(types$1._finally) ? this.parseBlock() : null; + if (!node.handler && !node.finalizer) + { this.raise(node.start, "Missing catch or finally clause"); } + return this.finishNode(node, "TryStatement") + }; - var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"; + pp$8.parseVarStatement = function(node, kind) { + this.next(); + this.parseVar(node, false, kind); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration") + }; - var keywords$1 = { - 5: ecma5AndLessKeywords, - "5module": ecma5AndLessKeywords + " export import", - 6: ecma5AndLessKeywords + " const class extends export import super" + pp$8.parseWhileStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + this.labels.push(loopLabel); + node.body = this.parseStatement("while"); + this.labels.pop(); + return this.finishNode(node, "WhileStatement") }; - var keywordRelationalOperator = /^in(stanceof)?$/; + pp$8.parseWithStatement = function(node) { + if (this.strict) { this.raise(this.start, "'with' in strict mode"); } + this.next(); + node.object = this.parseParenExpression(); + node.body = this.parseStatement("with"); + return this.finishNode(node, "WithStatement") + }; - // ## Character categories + pp$8.parseEmptyStatement = function(node) { + this.next(); + return this.finishNode(node, "EmptyStatement") + }; - var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); - var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); + pp$8.parseLabeledStatement = function(node, maybeName, expr, context) { + for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1) + { + var label = list[i$1]; - // This has a complexity linear to the value of the code. The - // assumption is that looking up astral identifier characters is - // rare. - function isInAstralSet(code, set) { - var pos = 0x10000; - for (var i = 0; i < set.length; i += 2) { - pos += set[i]; - if (pos > code) { return false } - pos += set[i + 1]; - if (pos >= code) { return true } + if (label.name === maybeName) + { this.raise(expr.start, "Label '" + maybeName + "' is already declared"); + } } + var kind = this.type.isLoop ? "loop" : this.type === types$1._switch ? "switch" : null; + for (var i = this.labels.length - 1; i >= 0; i--) { + var label$1 = this.labels[i]; + if (label$1.statementStart === node.start) { + // Update information about previous labels on this node + label$1.statementStart = this.start; + label$1.kind = kind; + } else { break } } - return false - } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); + node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label"); + this.labels.pop(); + node.label = expr; + return this.finishNode(node, "LabeledStatement") + }; - // Test whether a given character code starts an identifier. + pp$8.parseExpressionStatement = function(node, expr) { + node.expression = expr; + this.semicolon(); + return this.finishNode(node, "ExpressionStatement") + }; - function isIdentifierStart(code, astral) { - if (code < 65) { return code === 36 } - if (code < 91) { return true } - if (code < 97) { return code === 95 } - if (code < 123) { return true } - if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) } - if (astral === false) { return false } - return isInAstralSet(code, astralIdentifierStartCodes) - } + // Parse a semicolon-enclosed block of statements, handling `"use + // strict"` declarations when `allowStrict` is true (used for + // function bodies). - // Test whether a given character is part of an identifier. + pp$8.parseBlock = function(createNewLexicalScope, node, exitStrict) { + if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; + if ( node === void 0 ) node = this.startNode(); - function isIdentifierChar(code, astral) { - if (code < 48) { return code === 36 } - if (code < 58) { return true } - if (code < 65) { return false } - if (code < 91) { return true } - if (code < 97) { return code === 95 } - if (code < 123) { return true } - if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) } - if (astral === false) { return false } - return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) - } + node.body = []; + this.expect(types$1.braceL); + if (createNewLexicalScope) { this.enterScope(0); } + while (this.type !== types$1.braceR) { + var stmt = this.parseStatement(null); + node.body.push(stmt); + } + if (exitStrict) { this.strict = false; } + this.next(); + if (createNewLexicalScope) { this.exitScope(); } + return this.finishNode(node, "BlockStatement") + }; - // ## Token types + // Parse a regular `for` loop. The disambiguation code in + // `parseStatement` will already have parsed the init statement or + // expression. - // The assignment of fine-grained, information-carrying type objects - // allows the tokenizer to store the information it has about a - // token in a way that is very cheap for the parser to look up. + pp$8.parseFor = function(node, init) { + node.init = init; + this.expect(types$1.semi); + node.test = this.type === types$1.semi ? null : this.parseExpression(); + this.expect(types$1.semi); + node.update = this.type === types$1.parenR ? null : this.parseExpression(); + this.expect(types$1.parenR); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, "ForStatement") + }; - // All token type variables start with an underscore, to make them - // easy to recognize. + // Parse a `for`/`in` and `for`/`of` loop, which are almost + // same from parser's perspective. - // The `beforeExpr` property is used to disambiguate between regular - // expressions and divisions. It is set on all token types that can - // be followed by an expression (thus, a slash after them would be a - // regular expression). - // - // The `startsExpr` property is used to check if the token ends a - // `yield` expression. It is set on all token types that either can - // directly start an expression (like a quotation mark) or can - // continue an expression (like the body of a string). - // - // `isLoop` marks a keyword as starting a loop, which is important - // to know when parsing a label, in order to allow or disallow - // continue jumps to that label. + pp$8.parseForIn = function(node, init) { + var isForIn = this.type === types$1._in; + this.next(); - var TokenType = function TokenType(label, conf) { - if ( conf === void 0 ) conf = {}; + if ( + init.type === "VariableDeclaration" && + init.declarations[0].init != null && + ( + !isForIn || + this.options.ecmaVersion < 8 || + this.strict || + init.kind !== "var" || + init.declarations[0].id.type !== "Identifier" + ) + ) { + this.raise( + init.start, + ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer") + ); + } + node.left = init; + node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign(); + this.expect(types$1.parenR); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement") + }; - this.label = label; - this.keyword = conf.keyword; - this.beforeExpr = !!conf.beforeExpr; - this.startsExpr = !!conf.startsExpr; - this.isLoop = !!conf.isLoop; - this.isAssign = !!conf.isAssign; - this.prefix = !!conf.prefix; - this.postfix = !!conf.postfix; - this.binop = conf.binop || null; - this.updateContext = null; + // Parse a list of variable declarations. + + pp$8.parseVar = function(node, isFor, kind) { + node.declarations = []; + node.kind = kind; + for (;;) { + var decl = this.startNode(); + this.parseVarId(decl, kind); + if (this.eat(types$1.eq)) { + decl.init = this.parseMaybeAssign(isFor); + } else if (kind === "const" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) { + this.unexpected(); + } else if (decl.id.type !== "Identifier" && !(isFor && (this.type === types$1._in || this.isContextual("of")))) { + this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value"); + } else { + decl.init = null; + } + node.declarations.push(this.finishNode(decl, "VariableDeclarator")); + if (!this.eat(types$1.comma)) { break } + } + return node }; - function binop(name, prec) { - return new TokenType(name, {beforeExpr: true, binop: prec}) - } - var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true}; + pp$8.parseVarId = function(decl, kind) { + decl.id = this.parseBindingAtom(); + this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); + }; - // Map keyword names to token types. + var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4; - var keywords = {}; + // Parse a function declaration or literal (depending on the + // `statement & FUNC_STATEMENT`). - // Succinct definitions of keyword token types - function kw(name, options) { - if ( options === void 0 ) options = {}; + // Remove `allowExpressionBody` for 7.0.0, as it is only called with false + pp$8.parseFunction = function(node, statement, allowExpressionBody, isAsync, forInit) { + this.initFunction(node); + if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) { + if (this.type === types$1.star && (statement & FUNC_HANGING_STATEMENT)) + { this.unexpected(); } + node.generator = this.eat(types$1.star); + } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } - options.keyword = name; - return keywords[name] = new TokenType(name, options) - } + if (statement & FUNC_STATEMENT) { + node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types$1.name ? null : this.parseIdent(); + if (node.id && !(statement & FUNC_HANGING_STATEMENT)) + // If it is a regular function declaration in sloppy mode, then it is + // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding + // mode depends on properties of the current scope (see + // treatFunctionsAsVar). + { this.checkLValSimple(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); } + } - var types$1 = { - num: new TokenType("num", startsExpr), - regexp: new TokenType("regexp", startsExpr), - string: new TokenType("string", startsExpr), - name: new TokenType("name", startsExpr), - privateId: new TokenType("privateId", startsExpr), - eof: new TokenType("eof"), + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(node.async, node.generator)); - // Punctuation token types. - bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), - bracketR: new TokenType("]"), - braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), - braceR: new TokenType("}"), - parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), - parenR: new TokenType(")"), - comma: new TokenType(",", beforeExpr), - semi: new TokenType(";", beforeExpr), - colon: new TokenType(":", beforeExpr), - dot: new TokenType("."), - question: new TokenType("?", beforeExpr), - questionDot: new TokenType("?."), - arrow: new TokenType("=>", beforeExpr), - template: new TokenType("template"), - invalidTemplate: new TokenType("invalidTemplate"), - ellipsis: new TokenType("...", beforeExpr), - backQuote: new TokenType("`", startsExpr), - dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), + if (!(statement & FUNC_STATEMENT)) + { node.id = this.type === types$1.name ? this.parseIdent() : null; } - // Operators. These carry several kinds of properties to help the - // parser use them properly (the presence of these properties is - // what categorizes them as operators). - // - // `binop`, when present, specifies that this operator is a binary - // operator, and will refer to its precedence. - // - // `prefix` and `postfix` mark the operator as a prefix or postfix - // unary operator. - // - // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as - // binary operators with a very low precedence, that should result - // in AssignmentExpression nodes. + this.parseFunctionParams(node); + this.parseFunctionBody(node, allowExpressionBody, false, forInit); - eq: new TokenType("=", {beforeExpr: true, isAssign: true}), - assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), - incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), - prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}), - logicalOR: binop("||", 1), - logicalAND: binop("&&", 2), - bitwiseOR: binop("|", 3), - bitwiseXOR: binop("^", 4), - bitwiseAND: binop("&", 5), - equality: binop("==/!=/===/!==", 6), - relational: binop("/<=/>=", 7), - bitShift: binop("<>/>>>", 8), - plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), - modulo: binop("%", 10), - star: binop("*", 10), - slash: binop("/", 10), - starstar: new TokenType("**", {beforeExpr: true}), - coalesce: binop("??", 1), + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression") + }; - // Keyword token types. - _break: kw("break"), - _case: kw("case", beforeExpr), - _catch: kw("catch"), - _continue: kw("continue"), - _debugger: kw("debugger"), - _default: kw("default", beforeExpr), - _do: kw("do", {isLoop: true, beforeExpr: true}), - _else: kw("else", beforeExpr), - _finally: kw("finally"), - _for: kw("for", {isLoop: true}), - _function: kw("function", startsExpr), - _if: kw("if"), - _return: kw("return", beforeExpr), - _switch: kw("switch"), - _throw: kw("throw", beforeExpr), - _try: kw("try"), - _var: kw("var"), - _const: kw("const"), - _while: kw("while", {isLoop: true}), - _with: kw("with"), - _new: kw("new", {beforeExpr: true, startsExpr: true}), - _this: kw("this", startsExpr), - _super: kw("super", startsExpr), - _class: kw("class", startsExpr), - _extends: kw("extends", beforeExpr), - _export: kw("export"), - _import: kw("import", startsExpr), - _null: kw("null", startsExpr), - _true: kw("true", startsExpr), - _false: kw("false", startsExpr), - _in: kw("in", {beforeExpr: true, binop: 7}), - _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), - _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), - _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), - _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) + pp$8.parseFunctionParams = function(node) { + this.expect(types$1.parenL); + node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); }; - // Matches a whole line break (where CRLF is considered a single - // line break). Used to count lines. + // Parse a class declaration or literal (depending on the + // `isStatement` parameter). - var lineBreak = /\r\n?|\n|\u2028|\u2029/; - var lineBreakG = new RegExp(lineBreak.source, "g"); + pp$8.parseClass = function(node, isStatement) { + this.next(); - function isNewLine(code) { - return code === 10 || code === 13 || code === 0x2028 || code === 0x2029 - } + // ecma-262 14.6 Class Definitions + // A class definition is always strict mode code. + var oldStrict = this.strict; + this.strict = true; - function nextLineBreak(code, from, end) { - if ( end === void 0 ) end = code.length; + this.parseClassId(node, isStatement); + this.parseClassSuper(node); + var privateNameMap = this.enterClassBody(); + var classBody = this.startNode(); + var hadConstructor = false; + classBody.body = []; + this.expect(types$1.braceL); + while (this.type !== types$1.braceR) { + var element = this.parseClassElement(node.superClass !== null); + if (element) { + classBody.body.push(element); + if (element.type === "MethodDefinition" && element.kind === "constructor") { + if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); } + hadConstructor = true; + } else if (element.key && element.key.type === "PrivateIdentifier" && isPrivateNameConflicted(privateNameMap, element)) { + this.raiseRecoverable(element.key.start, ("Identifier '#" + (element.key.name) + "' has already been declared")); + } + } + } + this.strict = oldStrict; + this.next(); + node.body = this.finishNode(classBody, "ClassBody"); + this.exitClassBody(); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") + }; - for (var i = from; i < end; i++) { - var next = code.charCodeAt(i); - if (isNewLine(next)) - { return i < end - 1 && next === 13 && code.charCodeAt(i + 1) === 10 ? i + 2 : i + 1 } + pp$8.parseClassElement = function(constructorAllowsSuper) { + if (this.eat(types$1.semi)) { return null } + + var ecmaVersion = this.options.ecmaVersion; + var node = this.startNode(); + var keyName = ""; + var isGenerator = false; + var isAsync = false; + var kind = "method"; + var isStatic = false; + + if (this.eatContextual("static")) { + // Parse static init block + if (ecmaVersion >= 13 && this.eat(types$1.braceL)) { + this.parseClassStaticBlock(node); + return node + } + if (this.isClassElementNameStart() || this.type === types$1.star) { + isStatic = true; + } else { + keyName = "static"; + } + } + node.static = isStatic; + if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) { + if ((this.isClassElementNameStart() || this.type === types$1.star) && !this.canInsertSemicolon()) { + isAsync = true; + } else { + keyName = "async"; + } + } + if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types$1.star)) { + isGenerator = true; + } + if (!keyName && !isAsync && !isGenerator) { + var lastValue = this.value; + if (this.eatContextual("get") || this.eatContextual("set")) { + if (this.isClassElementNameStart()) { + kind = lastValue; + } else { + keyName = lastValue; + } + } } - return -1 - } - var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/; + // Parse element name + if (keyName) { + // 'async', 'get', 'set', or 'static' were not a keyword contextually. + // The last token is any of those. Make it the element name. + node.computed = false; + node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc); + node.key.name = keyName; + this.finishNode(node.key, "Identifier"); + } else { + this.parseClassElementName(node); + } - var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; + // Parse element value + if (ecmaVersion < 13 || this.type === types$1.parenL || kind !== "method" || isGenerator || isAsync) { + var isConstructor = !node.static && checkKeyName(node, "constructor"); + var allowsDirectSuper = isConstructor && constructorAllowsSuper; + // Couldn't move this check into the 'parseClassMethod' method for backward compatibility. + if (isConstructor && kind !== "method") { this.raise(node.key.start, "Constructor can't have get/set modifier"); } + node.kind = isConstructor ? "constructor" : kind; + this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper); + } else { + this.parseClassField(node); + } - var ref = Object.prototype; - var hasOwnProperty = ref.hasOwnProperty; - var toString = ref.toString; + return node + }; - var hasOwn = Object.hasOwn || (function (obj, propName) { return ( - hasOwnProperty.call(obj, propName) - ); }); + pp$8.isClassElementNameStart = function() { + return ( + this.type === types$1.name || + this.type === types$1.privateId || + this.type === types$1.num || + this.type === types$1.string || + this.type === types$1.bracketL || + this.type.keyword + ) + }; - var isArray = Array.isArray || (function (obj) { return ( - toString.call(obj) === "[object Array]" - ); }); + pp$8.parseClassElementName = function(element) { + if (this.type === types$1.privateId) { + if (this.value === "constructor") { + this.raise(this.start, "Classes can't have an element named '#constructor'"); + } + element.computed = false; + element.key = this.parsePrivateIdent(); + } else { + this.parsePropertyName(element); + } + }; - function wordsRegexp(words) { - return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$") - } + pp$8.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) { + // Check key and flags + var key = method.key; + if (method.kind === "constructor") { + if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } + if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } + } else if (method.static && checkKeyName(method, "prototype")) { + this.raise(key.start, "Classes may not have a static property named prototype"); + } - function codePointToString(code) { - // UTF-16 Decoding - if (code <= 0xFFFF) { return String.fromCharCode(code) } - code -= 0x10000; - return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00) - } + // Parse value + var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper); - var loneSurrogate = /(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/; + // Check value + if (method.kind === "get" && value.params.length !== 0) + { this.raiseRecoverable(value.start, "getter should have no params"); } + if (method.kind === "set" && value.params.length !== 1) + { this.raiseRecoverable(value.start, "setter should have exactly one param"); } + if (method.kind === "set" && value.params[0].type === "RestElement") + { this.raiseRecoverable(value.params[0].start, "Setter cannot use rest params"); } - // These are used when `options.locations` is on, for the - // `startLoc` and `endLoc` properties. + return this.finishNode(method, "MethodDefinition") + }; - var Position = function Position(line, col) { - this.line = line; - this.column = col; + pp$8.parseClassField = function(field) { + if (checkKeyName(field, "constructor")) { + this.raise(field.key.start, "Classes can't have a field named 'constructor'"); + } else if (field.static && checkKeyName(field, "prototype")) { + this.raise(field.key.start, "Classes can't have a static field named 'prototype'"); + } + + if (this.eat(types$1.eq)) { + // To raise SyntaxError if 'arguments' exists in the initializer. + var scope = this.currentThisScope(); + var inClassFieldInit = scope.inClassFieldInit; + scope.inClassFieldInit = true; + field.value = this.parseMaybeAssign(); + scope.inClassFieldInit = inClassFieldInit; + } else { + field.value = null; + } + this.semicolon(); + + return this.finishNode(field, "PropertyDefinition") }; - Position.prototype.offset = function offset (n) { - return new Position(this.line, this.column + n) + pp$8.parseClassStaticBlock = function(node) { + node.body = []; + + var oldLabels = this.labels; + this.labels = []; + this.enterScope(SCOPE_CLASS_STATIC_BLOCK | SCOPE_SUPER); + while (this.type !== types$1.braceR) { + var stmt = this.parseStatement(null); + node.body.push(stmt); + } + this.next(); + this.exitScope(); + this.labels = oldLabels; + + return this.finishNode(node, "StaticBlock") }; - var SourceLocation = function SourceLocation(p, start, end) { - this.start = start; - this.end = end; - if (p.sourceFile !== null) { this.source = p.sourceFile; } + pp$8.parseClassId = function(node, isStatement) { + if (this.type === types$1.name) { + node.id = this.parseIdent(); + if (isStatement) + { this.checkLValSimple(node.id, BIND_LEXICAL, false); } + } else { + if (isStatement === true) + { this.unexpected(); } + node.id = null; + } }; - // The `getLineInfo` function is mostly useful when the - // `locations` option is off (for performance reasons) and you - // want to find the line/column position for a given character - // offset. `input` should be the code string that the offset refers - // into. + pp$8.parseClassSuper = function(node) { + node.superClass = this.eat(types$1._extends) ? this.parseExprSubscripts(null, false) : null; + }; - function getLineInfo(input, offset) { - for (var line = 1, cur = 0;;) { - var nextBreak = nextLineBreak(input, cur, offset); - if (nextBreak < 0) { return new Position(line, offset - cur) } - ++line; - cur = nextBreak; + pp$8.enterClassBody = function() { + var element = {declared: Object.create(null), used: []}; + this.privateNameStack.push(element); + return element.declared + }; + + pp$8.exitClassBody = function() { + var ref = this.privateNameStack.pop(); + var declared = ref.declared; + var used = ref.used; + var len = this.privateNameStack.length; + var parent = len === 0 ? null : this.privateNameStack[len - 1]; + for (var i = 0; i < used.length; ++i) { + var id = used[i]; + if (!hasOwn(declared, id.name)) { + if (parent) { + parent.used.push(id); + } else { + this.raiseRecoverable(id.start, ("Private field '#" + (id.name) + "' must be declared in an enclosing class")); + } + } } - } + }; - // A second argument must be given to configure the parser process. - // These options are recognized (only `ecmaVersion` is required): + function isPrivateNameConflicted(privateNameMap, element) { + var name = element.key.name; + var curr = privateNameMap[name]; - var defaultOptions = { - // `ecmaVersion` indicates the ECMAScript version to parse. Must be - // either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 - // (2019), 11 (2020), 12 (2021), 13 (2022), 14 (2023), or `"latest"` - // (the latest version the library supports). This influences - // support for strict mode, the set of reserved words, and support - // for new syntax features. - ecmaVersion: null, - // `sourceType` indicates the mode the code should be parsed in. - // Can be either `"script"` or `"module"`. This influences global - // strict mode and parsing of `import` and `export` declarations. - sourceType: "script", - // `onInsertedSemicolon` can be a callback that will be called - // when a semicolon is automatically inserted. It will be passed - // the position of the comma as an offset, and if `locations` is - // enabled, it is given the location as a `{line, column}` object - // as second argument. - onInsertedSemicolon: null, - // `onTrailingComma` is similar to `onInsertedSemicolon`, but for - // trailing commas. - onTrailingComma: null, - // By default, reserved words are only enforced if ecmaVersion >= 5. - // Set `allowReserved` to a boolean value to explicitly turn this on - // an off. When this option has the value "never", reserved words - // and keywords can also not be used as property names. - allowReserved: null, - // When enabled, a return at the top level is not considered an - // error. - allowReturnOutsideFunction: false, - // When enabled, import/export statements are not constrained to - // appearing at the top of the program, and an import.meta expression - // in a script isn't considered an error. - allowImportExportEverywhere: false, - // By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022. - // When enabled, await identifiers are allowed to appear at the top-level scope, - // but they are still not allowed in non-async functions. - allowAwaitOutsideFunction: null, - // When enabled, super identifiers are not constrained to - // appearing in methods and do not raise an error when they appear elsewhere. - allowSuperOutsideMethod: null, - // When enabled, hashbang directive in the beginning of file is - // allowed and treated as a line comment. Enabled by default when - // `ecmaVersion` >= 2023. - allowHashBang: false, - // When `locations` is on, `loc` properties holding objects with - // `start` and `end` properties in `{line, column}` form (with - // line being 1-based and column 0-based) will be attached to the - // nodes. - locations: false, - // A function can be passed as `onToken` option, which will - // cause Acorn to call that function with object in the same - // format as tokens returned from `tokenizer().getToken()`. Note - // that you are not allowed to call the parser from the - // callback—that will corrupt its internal state. - onToken: null, - // A function can be passed as `onComment` option, which will - // cause Acorn to call that function with `(block, text, start, - // end)` parameters whenever a comment is skipped. `block` is a - // boolean indicating whether this is a block (`/* */`) comment, - // `text` is the content of the comment, and `start` and `end` are - // character offsets that denote the start and end of the comment. - // When the `locations` option is on, two more parameters are - // passed, the full `{line, column}` locations of the start and - // end of the comments. Note that you are not allowed to call the - // parser from the callback—that will corrupt its internal state. - onComment: null, - // Nodes have their start and end characters offsets recorded in - // `start` and `end` properties (directly on the node, rather than - // the `loc` object, which holds line/column data. To also add a - // [semi-standardized][range] `range` property holding a `[start, - // end]` array with the same numbers, set the `ranges` option to - // `true`. - // - // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 - ranges: false, - // It is possible to parse multiple files into a single AST by - // passing the tree produced by parsing the first file as - // `program` option in subsequent parses. This will add the - // toplevel forms of the parsed file to the `Program` (top) node - // of an existing parse tree. - program: null, - // When `locations` is on, you can pass this to record the source - // file in every node's `loc` object. - sourceFile: null, - // This value, if given, is stored in every node, whether - // `locations` is on or off. - directSourceFile: null, - // When enabled, parenthesized expressions are represented by - // (non-standard) ParenthesizedExpression nodes - preserveParens: false - }; - - // Interpret and default an options object - - var warnedAboutEcmaVersion = false; - - function getOptions(opts) { - var options = {}; - - for (var opt in defaultOptions) - { options[opt] = opts && hasOwn(opts, opt) ? opts[opt] : defaultOptions[opt]; } - - if (options.ecmaVersion === "latest") { - options.ecmaVersion = 1e8; - } else if (options.ecmaVersion == null) { - if (!warnedAboutEcmaVersion && typeof console === "object" && console.warn) { - warnedAboutEcmaVersion = true; - console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future."); - } - options.ecmaVersion = 11; - } else if (options.ecmaVersion >= 2015) { - options.ecmaVersion -= 2009; - } - - if (options.allowReserved == null) - { options.allowReserved = options.ecmaVersion < 5; } - - if (!opts || opts.allowHashBang == null) - { options.allowHashBang = options.ecmaVersion >= 14; } - - if (isArray(options.onToken)) { - var tokens = options.onToken; - options.onToken = function (token) { return tokens.push(token); }; + var next = "true"; + if (element.type === "MethodDefinition" && (element.kind === "get" || element.kind === "set")) { + next = (element.static ? "s" : "i") + element.kind; } - if (isArray(options.onComment)) - { options.onComment = pushComment(options, options.onComment); } - - return options - } - function pushComment(options, array) { - return function(block, text, start, end, startLoc, endLoc) { - var comment = { - type: block ? "Block" : "Line", - value: text, - start: start, - end: end - }; - if (options.locations) - { comment.loc = new SourceLocation(this, startLoc, endLoc); } - if (options.ranges) - { comment.range = [start, end]; } - array.push(comment); + // `class { get #a(){}; static set #a(_){} }` is also conflict. + if ( + curr === "iget" && next === "iset" || + curr === "iset" && next === "iget" || + curr === "sget" && next === "sset" || + curr === "sset" && next === "sget" + ) { + privateNameMap[name] = "true"; + return false + } else if (!curr) { + privateNameMap[name] = next; + return false + } else { + return true } } - // Each scope gets a bitset that may contain these flags - var - SCOPE_TOP = 1, - SCOPE_FUNCTION = 2, - SCOPE_ASYNC = 4, - SCOPE_GENERATOR = 8, - SCOPE_ARROW = 16, - SCOPE_SIMPLE_CATCH = 32, - SCOPE_SUPER = 64, - SCOPE_DIRECT_SUPER = 128, - SCOPE_CLASS_STATIC_BLOCK = 256, - SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK; - - function functionFlags(async, generator) { - return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0) + function checkKeyName(node, name) { + var computed = node.computed; + var key = node.key; + return !computed && ( + key.type === "Identifier" && key.name === name || + key.type === "Literal" && key.value === name + ) } - // Used in checkLVal* and declareName to determine the type of a binding - var - BIND_NONE = 0, // Not a binding - BIND_VAR = 1, // Var-style binding - BIND_LEXICAL = 2, // Let- or const-style binding - BIND_FUNCTION = 3, // Function declaration - BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding - BIND_OUTSIDE = 5; // Special case for function names as bound inside the function + // Parses module export declaration. - var Parser = function Parser(options, input, startPos) { - this.options = options = getOptions(options); - this.sourceFile = options.sourceFile; - this.keywords = wordsRegexp(keywords$1[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]); - var reserved = ""; - if (options.allowReserved !== true) { - reserved = reservedWords[options.ecmaVersion >= 6 ? 6 : options.ecmaVersion === 5 ? 5 : 3]; - if (options.sourceType === "module") { reserved += " await"; } + pp$8.parseExport = function(node, exports) { + this.next(); + // export * from '...' + if (this.eat(types$1.star)) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseModuleExportName(); + this.checkExport(exports, node.exported, this.lastTokStart); + } else { + node.exported = null; + } + } + this.expectContextual("from"); + if (this.type !== types$1.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + this.semicolon(); + return this.finishNode(node, "ExportAllDeclaration") } - this.reservedWords = wordsRegexp(reserved); - var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; - this.reservedWordsStrict = wordsRegexp(reservedStrict); - this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind); - this.input = String(input); - - // Used to signal to callers of `readWord1` whether the word - // contained any escape sequences. This is needed because words with - // escape sequences must not be interpreted as keywords. - this.containsEsc = false; - - // Set up token state - - // The current position of the tokenizer in the input. - if (startPos) { - this.pos = startPos; - this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1; - this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; - } else { - this.pos = this.lineStart = 0; - this.curLine = 1; + if (this.eat(types$1._default)) { // export default ... + this.checkExport(exports, "default", this.lastTokStart); + var isAsync; + if (this.type === types$1._function || (isAsync = this.isAsyncFunction())) { + var fNode = this.startNode(); + this.next(); + if (isAsync) { this.next(); } + node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync); + } else if (this.type === types$1._class) { + var cNode = this.startNode(); + node.declaration = this.parseClass(cNode, "nullableID"); + } else { + node.declaration = this.parseMaybeAssign(); + this.semicolon(); + } + return this.finishNode(node, "ExportDefaultDeclaration") } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(null); + if (node.declaration.type === "VariableDeclaration") + { this.checkVariableExport(exports, node.declaration.declarations); } + else + { this.checkExport(exports, node.declaration.id, node.declaration.id.start); } + node.specifiers = []; + node.source = null; + } else { // export { x, y as z } [from '...'] + node.declaration = null; + node.specifiers = this.parseExportSpecifiers(exports); + if (this.eatContextual("from")) { + if (this.type !== types$1.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + } else { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) { + // check for keywords used as local names + var spec = list[i]; - // Properties of the current token: - // Its type - this.type = types$1.eof; - // For tokens that include more information than their type, the value - this.value = null; - // Its start and end offset - this.start = this.end = this.pos; - // And, if locations are used, the {line, column} object - // corresponding to those offsets - this.startLoc = this.endLoc = this.curPosition(); - - // Position information for the previous token - this.lastTokEndLoc = this.lastTokStartLoc = null; - this.lastTokStart = this.lastTokEnd = this.pos; - - // The context stack is used to superficially track syntactic - // context to predict whether a regular expression is allowed in a - // given position. - this.context = this.initialContext(); - this.exprAllowed = true; - - // Figure out if it's a module code. - this.inModule = options.sourceType === "module"; - this.strict = this.inModule || this.strictDirective(this.pos); + this.checkUnreserved(spec.local); + // check if export is defined + this.checkLocalExport(spec.local); - // Used to signify the start of a potential arrow function - this.potentialArrowAt = -1; - this.potentialArrowInForAwait = false; + if (spec.local.type === "Literal") { + this.raise(spec.local.start, "A string literal cannot be used as an exported binding without `from`."); + } + } - // Positions to delayed-check that yield/await does not exist in default parameters. - this.yieldPos = this.awaitPos = this.awaitIdentPos = 0; - // Labels in scope. - this.labels = []; - // Thus-far undefined exports. - this.undefinedExports = Object.create(null); + node.source = null; + } + this.semicolon(); + } + return this.finishNode(node, "ExportNamedDeclaration") + }; - // If enabled, skip leading hashbang line. - if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") - { this.skipLineComment(2); } + pp$8.checkExport = function(exports, name, pos) { + if (!exports) { return } + if (typeof name !== "string") + { name = name.type === "Identifier" ? name.name : name.value; } + if (hasOwn(exports, name)) + { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); } + exports[name] = true; + }; - // Scope tracking for duplicate variable names (see scope.js) - this.scopeStack = []; - this.enterScope(SCOPE_TOP); + pp$8.checkPatternExport = function(exports, pat) { + var type = pat.type; + if (type === "Identifier") + { this.checkExport(exports, pat, pat.start); } + else if (type === "ObjectPattern") + { for (var i = 0, list = pat.properties; i < list.length; i += 1) + { + var prop = list[i]; - // For RegExp validation - this.regexpState = null; + this.checkPatternExport(exports, prop); + } } + else if (type === "ArrayPattern") + { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) { + var elt = list$1[i$1]; - // The stack of private names. - // Each element has two properties: 'declared' and 'used'. - // When it exited from the outermost class definition, all used private names must be declared. - this.privateNameStack = []; + if (elt) { this.checkPatternExport(exports, elt); } + } } + else if (type === "Property") + { this.checkPatternExport(exports, pat.value); } + else if (type === "AssignmentPattern") + { this.checkPatternExport(exports, pat.left); } + else if (type === "RestElement") + { this.checkPatternExport(exports, pat.argument); } + else if (type === "ParenthesizedExpression") + { this.checkPatternExport(exports, pat.expression); } }; - var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },allowNewDotTarget: { configurable: true },inClassStaticBlock: { configurable: true } }; + pp$8.checkVariableExport = function(exports, decls) { + if (!exports) { return } + for (var i = 0, list = decls; i < list.length; i += 1) + { + var decl = list[i]; - Parser.prototype.parse = function parse () { - var node = this.options.program || this.startNode(); - this.nextToken(); - return this.parseTopLevel(node) + this.checkPatternExport(exports, decl.id); + } }; - prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 }; + pp$8.shouldParseExportStatement = function() { + return this.type.keyword === "var" || + this.type.keyword === "const" || + this.type.keyword === "class" || + this.type.keyword === "function" || + this.isLet() || + this.isAsyncFunction() + }; - prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 && !this.currentVarScope().inClassFieldInit }; + // Parses a comma-separated list of module exports. - prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 && !this.currentVarScope().inClassFieldInit }; + pp$8.parseExportSpecifiers = function(exports) { + var nodes = [], first = true; + // export { x, y as z } [from '...'] + this.expect(types$1.braceL); + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } - prototypeAccessors.canAwait.get = function () { - for (var i = this.scopeStack.length - 1; i >= 0; i--) { - var scope = this.scopeStack[i]; - if (scope.inClassFieldInit || scope.flags & SCOPE_CLASS_STATIC_BLOCK) { return false } - if (scope.flags & SCOPE_FUNCTION) { return (scope.flags & SCOPE_ASYNC) > 0 } + var node = this.startNode(); + node.local = this.parseModuleExportName(); + node.exported = this.eatContextual("as") ? this.parseModuleExportName() : node.local; + this.checkExport( + exports, + node.exported, + node.exported.start + ); + nodes.push(this.finishNode(node, "ExportSpecifier")); } - return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction - }; - - prototypeAccessors.allowSuper.get = function () { - var ref = this.currentThisScope(); - var flags = ref.flags; - var inClassFieldInit = ref.inClassFieldInit; - return (flags & SCOPE_SUPER) > 0 || inClassFieldInit || this.options.allowSuperOutsideMethod + return nodes }; - prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 }; - - prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) }; + // Parses import declaration. - prototypeAccessors.allowNewDotTarget.get = function () { - var ref = this.currentThisScope(); - var flags = ref.flags; - var inClassFieldInit = ref.inClassFieldInit; - return (flags & (SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK)) > 0 || inClassFieldInit + pp$8.parseImport = function(node) { + this.next(); + // import '...' + if (this.type === types$1.string) { + node.specifiers = empty$1; + node.source = this.parseExprAtom(); + } else { + node.specifiers = this.parseImportSpecifiers(); + this.expectContextual("from"); + node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected(); + } + this.semicolon(); + return this.finishNode(node, "ImportDeclaration") }; - prototypeAccessors.inClassStaticBlock.get = function () { - return (this.currentVarScope().flags & SCOPE_CLASS_STATIC_BLOCK) > 0 - }; + // Parses a comma-separated list of module imports. - Parser.extend = function extend () { - var plugins = [], len = arguments.length; - while ( len-- ) plugins[ len ] = arguments[ len ]; + pp$8.parseImportSpecifiers = function() { + var nodes = [], first = true; + if (this.type === types$1.name) { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode(); + node.local = this.parseIdent(); + this.checkLValSimple(node.local, BIND_LEXICAL); + nodes.push(this.finishNode(node, "ImportDefaultSpecifier")); + if (!this.eat(types$1.comma)) { return nodes } + } + if (this.type === types$1.star) { + var node$1 = this.startNode(); + this.next(); + this.expectContextual("as"); + node$1.local = this.parseIdent(); + this.checkLValSimple(node$1.local, BIND_LEXICAL); + nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); + return nodes + } + this.expect(types$1.braceL); + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } - var cls = this; - for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); } - return cls + var node$2 = this.startNode(); + node$2.imported = this.parseModuleExportName(); + if (this.eatContextual("as")) { + node$2.local = this.parseIdent(); + } else { + this.checkUnreserved(node$2.imported); + node$2.local = node$2.imported; + } + this.checkLValSimple(node$2.local, BIND_LEXICAL); + nodes.push(this.finishNode(node$2, "ImportSpecifier")); + } + return nodes }; - Parser.parse = function parse (input, options) { - return new this(options, input).parse() + pp$8.parseModuleExportName = function() { + if (this.options.ecmaVersion >= 13 && this.type === types$1.string) { + var stringLiteral = this.parseLiteral(this.value); + if (loneSurrogate.test(stringLiteral.value)) { + this.raise(stringLiteral.start, "An export name cannot include a lone surrogate."); + } + return stringLiteral + } + return this.parseIdent(true) }; - Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) { - var parser = new this(options, input, pos); - parser.nextToken(); - return parser.parseExpression() + // Set `ExpressionStatement#directive` property for directive prologues. + pp$8.adaptDirectivePrologue = function(statements) { + for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { + statements[i].directive = statements[i].expression.raw.slice(1, -1); + } }; - - Parser.tokenizer = function tokenizer (input, options) { - return new this(options, input) + pp$8.isDirectiveCandidate = function(statement) { + return ( + this.options.ecmaVersion >= 5 && + statement.type === "ExpressionStatement" && + statement.expression.type === "Literal" && + typeof statement.expression.value === "string" && + // Reject parenthesized strings. + (this.input[statement.start] === "\"" || this.input[statement.start] === "'") + ) }; - Object.defineProperties( Parser.prototype, prototypeAccessors ); - - var pp$9 = Parser.prototype; + var pp$7 = Parser.prototype; - // ## Parser utilities + // Convert existing expression atom to assignable pattern + // if possible. - var literal = /^(?:'((?:\\.|[^'\\])*?)'|"((?:\\.|[^"\\])*?)")/; - pp$9.strictDirective = function(start) { - if (this.options.ecmaVersion < 5) { return false } - for (;;) { - // Try to find string literal. - skipWhiteSpace.lastIndex = start; - start += skipWhiteSpace.exec(this.input)[0].length; - var match = literal.exec(this.input.slice(start)); - if (!match) { return false } - if ((match[1] || match[2]) === "use strict") { - skipWhiteSpace.lastIndex = start + match[0].length; - var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length; - var next = this.input.charAt(end); - return next === ";" || next === "}" || - (lineBreak.test(spaceAfter[0]) && - !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "=")) - } - start += match[0].length; + pp$7.toAssignable = function(node, isBinding, refDestructuringErrors) { + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + { this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); } + break - // Skip semicolon, if any. - skipWhiteSpace.lastIndex = start; - start += skipWhiteSpace.exec(this.input)[0].length; - if (this.input[start] === ";") - { start++; } - } - }; + case "ObjectPattern": + case "ArrayPattern": + case "AssignmentPattern": + case "RestElement": + break - // Predicate that tests whether the next token is of the given - // type, and if yes, consumes it as a side effect. + case "ObjectExpression": + node.type = "ObjectPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; - pp$9.eat = function(type) { - if (this.type === type) { - this.next(); - return true - } else { - return false - } - }; + this.toAssignable(prop, isBinding); + // Early error: + // AssignmentRestProperty[Yield, Await] : + // `...` DestructuringAssignmentTarget[Yield, Await] + // + // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. + if ( + prop.type === "RestElement" && + (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") + ) { + this.raise(prop.argument.start, "Unexpected token"); + } + } + break - // Tests whether parsed token is a contextual keyword. + case "Property": + // AssignmentProperty has type === "Property" + if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } + this.toAssignable(node.value, isBinding); + break - pp$9.isContextual = function(name) { - return this.type === types$1.name && this.value === name && !this.containsEsc - }; + case "ArrayExpression": + node.type = "ArrayPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + this.toAssignableList(node.elements, isBinding); + break - // Consumes contextual keyword if possible. + case "SpreadElement": + node.type = "RestElement"; + this.toAssignable(node.argument, isBinding); + if (node.argument.type === "AssignmentPattern") + { this.raise(node.argument.start, "Rest elements cannot have a default value"); } + break - pp$9.eatContextual = function(name) { - if (!this.isContextual(name)) { return false } - this.next(); - return true - }; + case "AssignmentExpression": + if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); } + node.type = "AssignmentPattern"; + delete node.operator; + this.toAssignable(node.left, isBinding); + break - // Asserts that following token is given contextual keyword. + case "ParenthesizedExpression": + this.toAssignable(node.expression, isBinding, refDestructuringErrors); + break - pp$9.expectContextual = function(name) { - if (!this.eatContextual(name)) { this.unexpected(); } - }; + case "ChainExpression": + this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side"); + break - // Test whether a semicolon can be inserted at the current position. + case "MemberExpression": + if (!isBinding) { break } - pp$9.canInsertSemicolon = function() { - return this.type === types$1.eof || - this.type === types$1.braceR || - lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + default: + this.raise(node.start, "Assigning to rvalue"); + } + } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + return node }; - pp$9.insertSemicolon = function() { - if (this.canInsertSemicolon()) { - if (this.options.onInsertedSemicolon) - { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); } - return true + // Convert list of expression atoms to binding list. + + pp$7.toAssignableList = function(exprList, isBinding) { + var end = exprList.length; + for (var i = 0; i < end; i++) { + var elt = exprList[i]; + if (elt) { this.toAssignable(elt, isBinding); } + } + if (end) { + var last = exprList[end - 1]; + if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + { this.unexpected(last.argument.start); } } + return exprList }; - // Consume a semicolon, or, failing that, see if we are allowed to - // pretend that there is a semicolon at this position. + // Parses spread element. - pp$9.semicolon = function() { - if (!this.eat(types$1.semi) && !this.insertSemicolon()) { this.unexpected(); } + pp$7.parseSpread = function(refDestructuringErrors) { + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeAssign(false, refDestructuringErrors); + return this.finishNode(node, "SpreadElement") }; - pp$9.afterTrailingComma = function(tokType, notNext) { - if (this.type === tokType) { - if (this.options.onTrailingComma) - { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); } - if (!notNext) - { this.next(); } - return true - } - }; + pp$7.parseRestBinding = function() { + var node = this.startNode(); + this.next(); - // Expect a token of a given type. If found, consume it, otherwise, - // raise an unexpected token error. + // RestElement inside of a function parameter must be an identifier + if (this.options.ecmaVersion === 6 && this.type !== types$1.name) + { this.unexpected(); } - pp$9.expect = function(type) { - this.eat(type) || this.unexpected(); + node.argument = this.parseBindingAtom(); + + return this.finishNode(node, "RestElement") }; - // Raise an unexpected token error. + // Parses lvalue (assignable) atom. - pp$9.unexpected = function(pos) { - this.raise(pos != null ? pos : this.start, "Unexpected token"); - }; + pp$7.parseBindingAtom = function() { + if (this.options.ecmaVersion >= 6) { + switch (this.type) { + case types$1.bracketL: + var node = this.startNode(); + this.next(); + node.elements = this.parseBindingList(types$1.bracketR, true, true); + return this.finishNode(node, "ArrayPattern") - var DestructuringErrors = function DestructuringErrors() { - this.shorthandAssign = - this.trailingComma = - this.parenthesizedAssign = - this.parenthesizedBind = - this.doubleProto = - -1; + case types$1.braceL: + return this.parseObj(true) + } + } + return this.parseIdent() }; - pp$9.checkPatternErrors = function(refDestructuringErrors, isAssign) { - if (!refDestructuringErrors) { return } - if (refDestructuringErrors.trailingComma > -1) - { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); } - var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind; - if (parens > -1) { this.raiseRecoverable(parens, isAssign ? "Assigning to rvalue" : "Parenthesized pattern"); } + pp$7.parseBindingList = function(close, allowEmpty, allowTrailingComma) { + var elts = [], first = true; + while (!this.eat(close)) { + if (first) { first = false; } + else { this.expect(types$1.comma); } + if (allowEmpty && this.type === types$1.comma) { + elts.push(null); + } else if (allowTrailingComma && this.afterTrailingComma(close)) { + break + } else if (this.type === types$1.ellipsis) { + var rest = this.parseRestBinding(); + this.parseBindingListItem(rest); + elts.push(rest); + if (this.type === types$1.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); } + this.expect(close); + break + } else { + var elem = this.parseMaybeDefault(this.start, this.startLoc); + this.parseBindingListItem(elem); + elts.push(elem); + } + } + return elts }; - pp$9.checkExpressionErrors = function(refDestructuringErrors, andThrow) { - if (!refDestructuringErrors) { return false } - var shorthandAssign = refDestructuringErrors.shorthandAssign; - var doubleProto = refDestructuringErrors.doubleProto; - if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 } - if (shorthandAssign >= 0) - { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); } - if (doubleProto >= 0) - { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); } + pp$7.parseBindingListItem = function(param) { + return param }; - pp$9.checkYieldAwaitInDefaultParams = function() { - if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) - { this.raise(this.yieldPos, "Yield expression cannot be a default value"); } - if (this.awaitPos) - { this.raise(this.awaitPos, "Await expression cannot be a default value"); } - }; + // Parses assignment pattern around given atom if possible. - pp$9.isSimpleAssignTarget = function(expr) { - if (expr.type === "ParenthesizedExpression") - { return this.isSimpleAssignTarget(expr.expression) } - return expr.type === "Identifier" || expr.type === "MemberExpression" + pp$7.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom(); + if (this.options.ecmaVersion < 6 || !this.eat(types$1.eq)) { return left } + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.right = this.parseMaybeAssign(); + return this.finishNode(node, "AssignmentPattern") }; - var pp$8 = Parser.prototype; + // The following three functions all verify that a node is an lvalue — + // something that can be bound, or assigned to. In order to do so, they perform + // a variety of checks: + // + // - Check that none of the bound/assigned-to identifiers are reserved words. + // - Record name declarations for bindings in the appropriate scope. + // - Check duplicate argument names, if checkClashes is set. + // + // If a complex binding pattern is encountered (e.g., object and array + // destructuring), the entire pattern is recursively checked. + // + // There are three versions of checkLVal*() appropriate for different + // circumstances: + // + // - checkLValSimple() shall be used if the syntactic construct supports + // nothing other than identifiers and member expressions. Parenthesized + // expressions are also correctly handled. This is generally appropriate for + // constructs for which the spec says + // + // > It is a Syntax Error if AssignmentTargetType of [the production] is not + // > simple. + // + // It is also appropriate for checking if an identifier is valid and not + // defined elsewhere, like import declarations or function/class identifiers. + // + // Examples where this is used include: + // a += …; + // import a from '…'; + // where a is the node to be checked. + // + // - checkLValPattern() shall be used if the syntactic construct supports + // anything checkLValSimple() supports, as well as object and array + // destructuring patterns. This is generally appropriate for constructs for + // which the spec says + // + // > It is a Syntax Error if [the production] is neither an ObjectLiteral nor + // > an ArrayLiteral and AssignmentTargetType of [the production] is not + // > simple. + // + // Examples where this is used include: + // (a = …); + // const a = …; + // try { … } catch (a) { … } + // where a is the node to be checked. + // + // - checkLValInnerPattern() shall be used if the syntactic construct supports + // anything checkLValPattern() supports, as well as default assignment + // patterns, rest elements, and other constructs that may appear within an + // object or array destructuring pattern. + // + // As a special case, function parameters also use checkLValInnerPattern(), + // as they also support defaults and rest constructs. + // + // These functions deliberately support both assignment and binding constructs, + // as the logic for both is exceedingly similar. If the node is the target of + // an assignment, then bindingType should be set to BIND_NONE. Otherwise, it + // should be set to the appropriate BIND_* constant, like BIND_VAR or + // BIND_LEXICAL. + // + // If the function is called with a non-BIND_NONE bindingType, then + // additionally a checkClashes object may be specified to allow checking for + // duplicate argument names. checkClashes is ignored if the provided construct + // is an assignment (i.e., bindingType is BIND_NONE). - // ### Statement parsing + pp$7.checkLValSimple = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; - // Parse a program. Initializes the parser, reads any number of - // statements, and wraps them in a Program node. Optionally takes a - // `program` argument. If present, the statements will be appended - // to its body instead of creating a new node. + var isBind = bindingType !== BIND_NONE; - pp$8.parseTopLevel = function(node) { - var exports = Object.create(null); - if (!node.body) { node.body = []; } - while (this.type !== types$1.eof) { - var stmt = this.parseStatement(null, true, exports); - node.body.push(stmt); - } - if (this.inModule) - { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1) - { - var name = list[i]; + switch (expr.type) { + case "Identifier": + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + { this.raiseRecoverable(expr.start, (isBind ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } + if (isBind) { + if (bindingType === BIND_LEXICAL && expr.name === "let") + { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); } + if (checkClashes) { + if (hasOwn(checkClashes, expr.name)) + { this.raiseRecoverable(expr.start, "Argument name clash"); } + checkClashes[expr.name] = true; + } + if (bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); } + } + break - this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined")); - } } - this.adaptDirectivePrologue(node.body); - this.next(); - node.sourceType = this.options.sourceType; - return this.finishNode(node, "Program") - }; + case "ChainExpression": + this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side"); + break - var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; + case "MemberExpression": + if (isBind) { this.raiseRecoverable(expr.start, "Binding member expression"); } + break - pp$8.isLet = function(context) { - if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false } - skipWhiteSpace.lastIndex = this.pos; - var skip = skipWhiteSpace.exec(this.input); - var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); - // For ambiguous cases, determine if a LexicalDeclaration (or only a - // Statement) is allowed here. If context is not empty then only a Statement - // is allowed. However, `let [` is an explicit negative lookahead for - // ExpressionStatement, so special-case it first. - if (nextCh === 91 || nextCh === 92) { return true } // '[', '/' - if (context) { return false } + case "ParenthesizedExpression": + if (isBind) { this.raiseRecoverable(expr.start, "Binding parenthesized expression"); } + return this.checkLValSimple(expr.expression, bindingType, checkClashes) - if (nextCh === 123 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '{', astral - if (isIdentifierStart(nextCh, true)) { - var pos = next + 1; - while (isIdentifierChar(nextCh = this.input.charCodeAt(pos), true)) { ++pos; } - if (nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } - var ident = this.input.slice(next, pos); - if (!keywordRelationalOperator.test(ident)) { return true } + default: + this.raise(expr.start, (isBind ? "Binding" : "Assigning to") + " rvalue"); } - return false }; - // check 'async [no LineTerminator here] function' - // - 'async /*foo*/ function' is OK. - // - 'async /*\n*/ function' is invalid. - pp$8.isAsyncFunction = function() { - if (this.options.ecmaVersion < 8 || !this.isContextual("async")) - { return false } + pp$7.checkLValPattern = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; - skipWhiteSpace.lastIndex = this.pos; - var skip = skipWhiteSpace.exec(this.input); - var next = this.pos + skip[0].length, after; - return !lineBreak.test(this.input.slice(this.pos, next)) && - this.input.slice(next, next + 8) === "function" && - (next + 8 === this.input.length || - !(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00)) - }; + switch (expr.type) { + case "ObjectPattern": + for (var i = 0, list = expr.properties; i < list.length; i += 1) { + var prop = list[i]; - // Parse a single statement. - // - // If expecting a statement and finding a slash operator, parse a - // regular expression literal. This is to handle cases like - // `if (foo) /blah/.exec(foo)`, where looking at the previous token - // does not help. + this.checkLValInnerPattern(prop, bindingType, checkClashes); + } + break - pp$8.parseStatement = function(context, topLevel, exports) { - var starttype = this.type, node = this.startNode(), kind; + case "ArrayPattern": + for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { + var elem = list$1[i$1]; - if (this.isLet(context)) { - starttype = types$1._var; - kind = "let"; + if (elem) { this.checkLValInnerPattern(elem, bindingType, checkClashes); } + } + break + + default: + this.checkLValSimple(expr, bindingType, checkClashes); } + }; - // Most types of statements are recognized by the keyword they - // start with. Many are trivial to parse, some require a bit of - // complexity. + pp$7.checkLValInnerPattern = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; - switch (starttype) { - case types$1._break: case types$1._continue: return this.parseBreakContinueStatement(node, starttype.keyword) - case types$1._debugger: return this.parseDebuggerStatement(node) - case types$1._do: return this.parseDoStatement(node) - case types$1._for: return this.parseForStatement(node) - case types$1._function: - // Function as sole body of either an if statement or a labeled statement - // works, but not when it is part of a labeled statement that is the sole - // body of an if statement. - if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); } - return this.parseFunctionStatement(node, false, !context) - case types$1._class: - if (context) { this.unexpected(); } - return this.parseClass(node, true) - case types$1._if: return this.parseIfStatement(node) - case types$1._return: return this.parseReturnStatement(node) - case types$1._switch: return this.parseSwitchStatement(node) - case types$1._throw: return this.parseThrowStatement(node) - case types$1._try: return this.parseTryStatement(node) - case types$1._const: case types$1._var: - kind = kind || this.value; - if (context && kind !== "var") { this.unexpected(); } - return this.parseVarStatement(node, kind) - case types$1._while: return this.parseWhileStatement(node) - case types$1._with: return this.parseWithStatement(node) - case types$1.braceL: return this.parseBlock(true, node) - case types$1.semi: return this.parseEmptyStatement(node) - case types$1._export: - case types$1._import: - if (this.options.ecmaVersion > 10 && starttype === types$1._import) { - skipWhiteSpace.lastIndex = this.pos; - var skip = skipWhiteSpace.exec(this.input); - var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); - if (nextCh === 40 || nextCh === 46) // '(' or '.' - { return this.parseExpressionStatement(node, this.parseExpression()) } - } + switch (expr.type) { + case "Property": + // AssignmentProperty has type === "Property" + this.checkLValInnerPattern(expr.value, bindingType, checkClashes); + break - if (!this.options.allowImportExportEverywhere) { - if (!topLevel) - { this.raise(this.start, "'import' and 'export' may only appear at the top level"); } - if (!this.inModule) - { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); } - } - return starttype === types$1._import ? this.parseImport(node) : this.parseExport(node, exports) + case "AssignmentPattern": + this.checkLValPattern(expr.left, bindingType, checkClashes); + break - // If the statement does not start with a statement keyword or a - // brace, it's an ExpressionStatement or LabeledStatement. We - // simply start parsing an expression, and afterwards, if the - // next token is a colon and the expression was a simple - // Identifier node, we switch to interpreting it as a label. - default: - if (this.isAsyncFunction()) { - if (context) { this.unexpected(); } - this.next(); - return this.parseFunctionStatement(node, true, !context) - } + case "RestElement": + this.checkLValPattern(expr.argument, bindingType, checkClashes); + break - var maybeName = this.value, expr = this.parseExpression(); - if (starttype === types$1.name && expr.type === "Identifier" && this.eat(types$1.colon)) - { return this.parseLabeledStatement(node, maybeName, expr, context) } - else { return this.parseExpressionStatement(node, expr) } + default: + this.checkLValPattern(expr, bindingType, checkClashes); } }; - pp$8.parseBreakContinueStatement = function(node, keyword) { - var isBreak = keyword === "break"; - this.next(); - if (this.eat(types$1.semi) || this.insertSemicolon()) { node.label = null; } - else if (this.type !== types$1.name) { this.unexpected(); } - else { - node.label = this.parseIdent(); - this.semicolon(); - } - - // Verify that there is an actual destination to break or - // continue to. - var i = 0; - for (; i < this.labels.length; ++i) { - var lab = this.labels[i]; - if (node.label == null || lab.name === node.label.name) { - if (lab.kind != null && (isBreak || lab.kind === "loop")) { break } - if (node.label && isBreak) { break } - } - } - if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); } - return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") - }; + // The algorithm used to determine whether a regexp can appear at a - pp$8.parseDebuggerStatement = function(node) { - this.next(); - this.semicolon(); - return this.finishNode(node, "DebuggerStatement") + var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { + this.token = token; + this.isExpr = !!isExpr; + this.preserveSpace = !!preserveSpace; + this.override = override; + this.generator = !!generator; }; - pp$8.parseDoStatement = function(node) { - this.next(); - this.labels.push(loopLabel); - node.body = this.parseStatement("do"); - this.labels.pop(); - this.expect(types$1._while); - node.test = this.parseParenExpression(); - if (this.options.ecmaVersion >= 6) - { this.eat(types$1.semi); } - else - { this.semicolon(); } - return this.finishNode(node, "DoWhileStatement") + var types = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", false), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }), + f_stat: new TokContext("function", false), + f_expr: new TokContext("function", true), + f_expr_gen: new TokContext("function", true, false, null, true), + f_gen: new TokContext("function", false, false, null, true) }; - // Disambiguating between a `for` and a `for`/`in` or `for`/`of` - // loop is non-trivial. Basically, we have to parse the init `var` - // statement or expression, disallowing the `in` operator (see - // the second parameter to `parseExpression`), and then check - // whether the next token is `in` or `of`. When there is no init - // part (semicolon immediately after the opening parenthesis), it - // is a regular `for` loop. - - pp$8.parseForStatement = function(node) { - this.next(); - var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual("await")) ? this.lastTokStart : -1; - this.labels.push(loopLabel); - this.enterScope(0); - this.expect(types$1.parenL); - if (this.type === types$1.semi) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, null) - } - var isLet = this.isLet(); - if (this.type === types$1._var || this.type === types$1._const || isLet) { - var init$1 = this.startNode(), kind = isLet ? "let" : this.value; - this.next(); - this.parseVar(init$1, true, kind); - this.finishNode(init$1, "VariableDeclaration"); - if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1) { - if (this.options.ecmaVersion >= 9) { - if (this.type === types$1._in) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - } else { node.await = awaitAt > -1; } - } - return this.parseForIn(node, init$1) - } - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, init$1) - } - var startsWithLet = this.isContextual("let"), isForOf = false; - var refDestructuringErrors = new DestructuringErrors; - var init = this.parseExpression(awaitAt > -1 ? "await" : true, refDestructuringErrors); - if (this.type === types$1._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual("of"))) { - if (this.options.ecmaVersion >= 9) { - if (this.type === types$1._in) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - } else { node.await = awaitAt > -1; } - } - if (startsWithLet && isForOf) { this.raise(init.start, "The left-hand side of a for-of loop may not start with 'let'."); } - this.toAssignable(init, false, refDestructuringErrors); - this.checkLValPattern(init); - return this.parseForIn(node, init) - } else { - this.checkExpressionErrors(refDestructuringErrors, true); - } - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, init) - }; + var pp$6 = Parser.prototype; - pp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) { - this.next(); - return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync) + pp$6.initialContext = function() { + return [types.b_stat] }; - pp$8.parseIfStatement = function(node) { - this.next(); - node.test = this.parseParenExpression(); - // allow function declarations in branches, but only in non-strict mode - node.consequent = this.parseStatement("if"); - node.alternate = this.eat(types$1._else) ? this.parseStatement("if") : null; - return this.finishNode(node, "IfStatement") + pp$6.curContext = function() { + return this.context[this.context.length - 1] }; - pp$8.parseReturnStatement = function(node) { - if (!this.inFunction && !this.options.allowReturnOutsideFunction) - { this.raise(this.start, "'return' outside of function"); } - this.next(); - - // In `return` (and `break`/`continue`), the keywords with - // optional arguments, we eagerly look for a semicolon or the - // possibility to insert one. + pp$6.braceIsBlock = function(prevType) { + var parent = this.curContext(); + if (parent === types.f_expr || parent === types.f_stat) + { return true } + if (prevType === types$1.colon && (parent === types.b_stat || parent === types.b_expr)) + { return !parent.isExpr } - if (this.eat(types$1.semi) || this.insertSemicolon()) { node.argument = null; } - else { node.argument = this.parseExpression(); this.semicolon(); } - return this.finishNode(node, "ReturnStatement") + // The check for `tt.name && exprAllowed` detects whether we are + // after a `yield` or `of` construct. See the `updateContext` for + // `tt.name`. + if (prevType === types$1._return || prevType === types$1.name && this.exprAllowed) + { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) } + if (prevType === types$1._else || prevType === types$1.semi || prevType === types$1.eof || prevType === types$1.parenR || prevType === types$1.arrow) + { return true } + if (prevType === types$1.braceL) + { return parent === types.b_stat } + if (prevType === types$1._var || prevType === types$1._const || prevType === types$1.name) + { return false } + return !this.exprAllowed }; - pp$8.parseSwitchStatement = function(node) { - this.next(); - node.discriminant = this.parseParenExpression(); - node.cases = []; - this.expect(types$1.braceL); - this.labels.push(switchLabel); - this.enterScope(0); - - // Statements under must be grouped (by label) in SwitchCase - // nodes. `cur` is used to keep the node that we are currently - // adding statements to. - - var cur; - for (var sawDefault = false; this.type !== types$1.braceR;) { - if (this.type === types$1._case || this.type === types$1._default) { - var isCase = this.type === types$1._case; - if (cur) { this.finishNode(cur, "SwitchCase"); } - node.cases.push(cur = this.startNode()); - cur.consequent = []; - this.next(); - if (isCase) { - cur.test = this.parseExpression(); - } else { - if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); } - sawDefault = true; - cur.test = null; - } - this.expect(types$1.colon); - } else { - if (!cur) { this.unexpected(); } - cur.consequent.push(this.parseStatement(null)); - } + pp$6.inGeneratorContext = function() { + for (var i = this.context.length - 1; i >= 1; i--) { + var context = this.context[i]; + if (context.token === "function") + { return context.generator } } - this.exitScope(); - if (cur) { this.finishNode(cur, "SwitchCase"); } - this.next(); // Closing brace - this.labels.pop(); - return this.finishNode(node, "SwitchStatement") + return false }; - pp$8.parseThrowStatement = function(node) { - this.next(); - if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) - { this.raise(this.lastTokEnd, "Illegal newline after throw"); } - node.argument = this.parseExpression(); - this.semicolon(); - return this.finishNode(node, "ThrowStatement") + pp$6.updateContext = function(prevType) { + var update, type = this.type; + if (type.keyword && prevType === types$1.dot) + { this.exprAllowed = false; } + else if (update = type.updateContext) + { update.call(this, prevType); } + else + { this.exprAllowed = type.beforeExpr; } }; - // Reused empty array added for node fields that are always empty. - - var empty$1 = []; + // Used to handle egde cases when token context could not be inferred correctly during tokenization phase - pp$8.parseTryStatement = function(node) { - this.next(); - node.block = this.parseBlock(); - node.handler = null; - if (this.type === types$1._catch) { - var clause = this.startNode(); - this.next(); - if (this.eat(types$1.parenL)) { - clause.param = this.parseBindingAtom(); - var simple = clause.param.type === "Identifier"; - this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0); - this.checkLValPattern(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL); - this.expect(types$1.parenR); - } else { - if (this.options.ecmaVersion < 10) { this.unexpected(); } - clause.param = null; - this.enterScope(0); - } - clause.body = this.parseBlock(false); - this.exitScope(); - node.handler = this.finishNode(clause, "CatchClause"); + pp$6.overrideContext = function(tokenCtx) { + if (this.curContext() !== tokenCtx) { + this.context[this.context.length - 1] = tokenCtx; } - node.finalizer = this.eat(types$1._finally) ? this.parseBlock() : null; - if (!node.handler && !node.finalizer) - { this.raise(node.start, "Missing catch or finally clause"); } - return this.finishNode(node, "TryStatement") }; - pp$8.parseVarStatement = function(node, kind) { - this.next(); - this.parseVar(node, false, kind); - this.semicolon(); - return this.finishNode(node, "VariableDeclaration") - }; + // Token-specific context update code - pp$8.parseWhileStatement = function(node) { - this.next(); - node.test = this.parseParenExpression(); - this.labels.push(loopLabel); - node.body = this.parseStatement("while"); - this.labels.pop(); - return this.finishNode(node, "WhileStatement") + types$1.parenR.updateContext = types$1.braceR.updateContext = function() { + if (this.context.length === 1) { + this.exprAllowed = true; + return + } + var out = this.context.pop(); + if (out === types.b_stat && this.curContext().token === "function") { + out = this.context.pop(); + } + this.exprAllowed = !out.isExpr; }; - pp$8.parseWithStatement = function(node) { - if (this.strict) { this.raise(this.start, "'with' in strict mode"); } - this.next(); - node.object = this.parseParenExpression(); - node.body = this.parseStatement("with"); - return this.finishNode(node, "WithStatement") + types$1.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr); + this.exprAllowed = true; }; - pp$8.parseEmptyStatement = function(node) { - this.next(); - return this.finishNode(node, "EmptyStatement") + types$1.dollarBraceL.updateContext = function() { + this.context.push(types.b_tmpl); + this.exprAllowed = true; }; - pp$8.parseLabeledStatement = function(node, maybeName, expr, context) { - for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1) - { - var label = list[i$1]; - - if (label.name === maybeName) - { this.raise(expr.start, "Label '" + maybeName + "' is already declared"); - } } - var kind = this.type.isLoop ? "loop" : this.type === types$1._switch ? "switch" : null; - for (var i = this.labels.length - 1; i >= 0; i--) { - var label$1 = this.labels[i]; - if (label$1.statementStart === node.start) { - // Update information about previous labels on this node - label$1.statementStart = this.start; - label$1.kind = kind; - } else { break } - } - this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); - node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label"); - this.labels.pop(); - node.label = expr; - return this.finishNode(node, "LabeledStatement") + types$1.parenL.updateContext = function(prevType) { + var statementParens = prevType === types$1._if || prevType === types$1._for || prevType === types$1._with || prevType === types$1._while; + this.context.push(statementParens ? types.p_stat : types.p_expr); + this.exprAllowed = true; }; - pp$8.parseExpressionStatement = function(node, expr) { - node.expression = expr; - this.semicolon(); - return this.finishNode(node, "ExpressionStatement") + types$1.incDec.updateContext = function() { + // tokExprAllowed stays unchanged }; - // Parse a semicolon-enclosed block of statements, handling `"use - // strict"` declarations when `allowStrict` is true (used for - // function bodies). + types$1._function.updateContext = types$1._class.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== types$1._else && + !(prevType === types$1.semi && this.curContext() !== types.p_stat) && + !(prevType === types$1._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) && + !((prevType === types$1.colon || prevType === types$1.braceL) && this.curContext() === types.b_stat)) + { this.context.push(types.f_expr); } + else + { this.context.push(types.f_stat); } + this.exprAllowed = false; + }; - pp$8.parseBlock = function(createNewLexicalScope, node, exitStrict) { - if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; - if ( node === void 0 ) node = this.startNode(); + types$1.backQuote.updateContext = function() { + if (this.curContext() === types.q_tmpl) + { this.context.pop(); } + else + { this.context.push(types.q_tmpl); } + this.exprAllowed = false; + }; - node.body = []; - this.expect(types$1.braceL); - if (createNewLexicalScope) { this.enterScope(0); } - while (this.type !== types$1.braceR) { - var stmt = this.parseStatement(null); - node.body.push(stmt); + types$1.star.updateContext = function(prevType) { + if (prevType === types$1._function) { + var index = this.context.length - 1; + if (this.context[index] === types.f_expr) + { this.context[index] = types.f_expr_gen; } + else + { this.context[index] = types.f_gen; } } - if (exitStrict) { this.strict = false; } - this.next(); - if (createNewLexicalScope) { this.exitScope(); } - return this.finishNode(node, "BlockStatement") + this.exprAllowed = true; }; - // Parse a regular `for` loop. The disambiguation code in - // `parseStatement` will already have parsed the init statement or - // expression. - - pp$8.parseFor = function(node, init) { - node.init = init; - this.expect(types$1.semi); - node.test = this.type === types$1.semi ? null : this.parseExpression(); - this.expect(types$1.semi); - node.update = this.type === types$1.parenR ? null : this.parseExpression(); - this.expect(types$1.parenR); - node.body = this.parseStatement("for"); - this.exitScope(); - this.labels.pop(); - return this.finishNode(node, "ForStatement") + types$1.name.updateContext = function(prevType) { + var allowed = false; + if (this.options.ecmaVersion >= 6 && prevType !== types$1.dot) { + if (this.value === "of" && !this.exprAllowed || + this.value === "yield" && this.inGeneratorContext()) + { allowed = true; } + } + this.exprAllowed = allowed; }; - // Parse a `for`/`in` and `for`/`of` loop, which are almost - // same from parser's perspective. - - pp$8.parseForIn = function(node, init) { - var isForIn = this.type === types$1._in; - this.next(); + // A recursive descent parser operates by defining functions for all - if ( - init.type === "VariableDeclaration" && - init.declarations[0].init != null && - ( - !isForIn || - this.options.ecmaVersion < 8 || - this.strict || - init.kind !== "var" || - init.declarations[0].id.type !== "Identifier" - ) - ) { - this.raise( - init.start, - ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer") - ); - } - node.left = init; - node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign(); - this.expect(types$1.parenR); - node.body = this.parseStatement("for"); - this.exitScope(); - this.labels.pop(); - return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement") - }; + var pp$5 = Parser.prototype; - // Parse a list of variable declarations. + // Check if property name clashes with already added. + // Object/class getters and setters are not allowed to clash — + // either with each other or with an init property — and in + // strict mode, init properties are also not allowed to be repeated. - pp$8.parseVar = function(node, isFor, kind) { - node.declarations = []; - node.kind = kind; - for (;;) { - var decl = this.startNode(); - this.parseVarId(decl, kind); - if (this.eat(types$1.eq)) { - decl.init = this.parseMaybeAssign(isFor); - } else if (kind === "const" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) { - this.unexpected(); - } else if (decl.id.type !== "Identifier" && !(isFor && (this.type === types$1._in || this.isContextual("of")))) { - this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value"); + pp$5.checkPropClash = function(prop, propHash, refDestructuringErrors) { + if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") + { return } + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + { return } + var key = prop.key; + var name; + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + var kind = prop.kind; + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) { + if (refDestructuringErrors) { + if (refDestructuringErrors.doubleProto < 0) { + refDestructuringErrors.doubleProto = key.start; + } + } else { + this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); + } + } + propHash.proto = true; + } + return + } + name = "$" + name; + var other = propHash[name]; + if (other) { + var redefinition; + if (kind === "init") { + redefinition = this.strict && other.init || other.get || other.set; } else { - decl.init = null; + redefinition = other.init || other[kind]; } - node.declarations.push(this.finishNode(decl, "VariableDeclarator")); - if (!this.eat(types$1.comma)) { break } + if (redefinition) + { this.raiseRecoverable(key.start, "Redefinition of property"); } + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + }; } - return node + other[kind] = true; }; - pp$8.parseVarId = function(decl, kind) { - decl.id = this.parseBindingAtom(); - this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); - }; + // ### Expression parsing - var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4; + // These nest, from the most general expression type at the top to + // 'atomic', nondivisible expression types at the bottom. Most of + // the functions will simply let the function(s) below them parse, + // and, *if* the syntactic construct they handle is present, wrap + // the AST node that the inner parser gave them in another node. - // Parse a function declaration or literal (depending on the - // `statement & FUNC_STATEMENT`). + // Parse a full expression. The optional arguments are used to + // forbid the `in` operator (in for loops initalization expressions) + // and provide reference for storing '=' operator inside shorthand + // property assignment in contexts where both object expression + // and object pattern might appear (so it's possible to raise + // delayed syntax error at correct position). - // Remove `allowExpressionBody` for 7.0.0, as it is only called with false - pp$8.parseFunction = function(node, statement, allowExpressionBody, isAsync, forInit) { - this.initFunction(node); - if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) { - if (this.type === types$1.star && (statement & FUNC_HANGING_STATEMENT)) - { this.unexpected(); } - node.generator = this.eat(types$1.star); + pp$5.parseExpression = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeAssign(forInit, refDestructuringErrors); + if (this.type === types$1.comma) { + var node = this.startNodeAt(startPos, startLoc); + node.expressions = [expr]; + while (this.eat(types$1.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); } + return this.finishNode(node, "SequenceExpression") } - if (this.options.ecmaVersion >= 8) - { node.async = !!isAsync; } + return expr + }; - if (statement & FUNC_STATEMENT) { - node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types$1.name ? null : this.parseIdent(); - if (node.id && !(statement & FUNC_HANGING_STATEMENT)) - // If it is a regular function declaration in sloppy mode, then it is - // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding - // mode depends on properties of the current scope (see - // treatFunctionsAsVar). - { this.checkLValSimple(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); } - } - - var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; - this.yieldPos = 0; - this.awaitPos = 0; - this.awaitIdentPos = 0; - this.enterScope(functionFlags(node.async, node.generator)); + // Parse an assignment expression. This includes applications of + // operators like `+=`. - if (!(statement & FUNC_STATEMENT)) - { node.id = this.type === types$1.name ? this.parseIdent() : null; } + pp$5.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) { + if (this.isContextual("yield")) { + if (this.inGenerator) { return this.parseYield(forInit) } + // The tokenizer will assume an expression is allowed after + // `yield`, but this isn't that kind of yield + else { this.exprAllowed = false; } + } - this.parseFunctionParams(node); - this.parseFunctionBody(node, allowExpressionBody, false, forInit); + var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldDoubleProto = -1; + if (refDestructuringErrors) { + oldParenAssign = refDestructuringErrors.parenthesizedAssign; + oldTrailingComma = refDestructuringErrors.trailingComma; + oldDoubleProto = refDestructuringErrors.doubleProto; + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1; + } else { + refDestructuringErrors = new DestructuringErrors; + ownDestructuringErrors = true; + } - this.yieldPos = oldYieldPos; - this.awaitPos = oldAwaitPos; - this.awaitIdentPos = oldAwaitIdentPos; - return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression") + var startPos = this.start, startLoc = this.startLoc; + if (this.type === types$1.parenL || this.type === types$1.name) { + this.potentialArrowAt = this.start; + this.potentialArrowInForAwait = forInit === "await"; + } + var left = this.parseMaybeConditional(forInit, refDestructuringErrors); + if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } + if (this.type.isAssign) { + var node = this.startNodeAt(startPos, startLoc); + node.operator = this.value; + if (this.type === types$1.eq) + { left = this.toAssignable(left, false, refDestructuringErrors); } + if (!ownDestructuringErrors) { + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1; + } + if (refDestructuringErrors.shorthandAssign >= left.start) + { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly + if (this.type === types$1.eq) + { this.checkLValPattern(left); } + else + { this.checkLValSimple(left); } + node.left = left; + this.next(); + node.right = this.parseMaybeAssign(forInit); + if (oldDoubleProto > -1) { refDestructuringErrors.doubleProto = oldDoubleProto; } + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } + } + if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; } + if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; } + return left }; - pp$8.parseFunctionParams = function(node) { - this.expect(types$1.parenL); - node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8); - this.checkYieldAwaitInDefaultParams(); + // Parse a ternary conditional (`?:`) operator. + + pp$5.parseMaybeConditional = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprOps(forInit, refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + if (this.eat(types$1.question)) { + var node = this.startNodeAt(startPos, startLoc); + node.test = expr; + node.consequent = this.parseMaybeAssign(); + this.expect(types$1.colon); + node.alternate = this.parseMaybeAssign(forInit); + return this.finishNode(node, "ConditionalExpression") + } + return expr }; - // Parse a class declaration or literal (depending on the - // `isStatement` parameter). + // Start the precedence parser. - pp$8.parseClass = function(node, isStatement) { - this.next(); + pp$5.parseExprOps = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeUnary(refDestructuringErrors, false, false, forInit); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit) + }; - // ecma-262 14.6 Class Definitions - // A class definition is always strict mode code. - var oldStrict = this.strict; - this.strict = true; + // Parse binary operators with the operator precedence parsing + // algorithm. `left` is the left-hand side of the operator. + // `minPrec` provides context that allows the function to stop and + // defer further parser to one of its callers when it encounters an + // operator that has a lower precedence than the set it is parsing. - this.parseClassId(node, isStatement); - this.parseClassSuper(node); - var privateNameMap = this.enterClassBody(); - var classBody = this.startNode(); - var hadConstructor = false; - classBody.body = []; - this.expect(types$1.braceL); - while (this.type !== types$1.braceR) { - var element = this.parseClassElement(node.superClass !== null); - if (element) { - classBody.body.push(element); - if (element.type === "MethodDefinition" && element.kind === "constructor") { - if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); } - hadConstructor = true; - } else if (element.key && element.key.type === "PrivateIdentifier" && isPrivateNameConflicted(privateNameMap, element)) { - this.raiseRecoverable(element.key.start, ("Identifier '#" + (element.key.name) + "' has already been declared")); + pp$5.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) { + var prec = this.type.binop; + if (prec != null && (!forInit || this.type !== types$1._in)) { + if (prec > minPrec) { + var logical = this.type === types$1.logicalOR || this.type === types$1.logicalAND; + var coalesce = this.type === types$1.coalesce; + if (coalesce) { + // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions. + // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error. + prec = types$1.logicalAND.binop; + } + var op = this.value; + this.next(); + var startPos = this.start, startLoc = this.startLoc; + var right = this.parseExprOp(this.parseMaybeUnary(null, false, false, forInit), startPos, startLoc, prec, forInit); + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce); + if ((logical && this.type === types$1.coalesce) || (coalesce && (this.type === types$1.logicalOR || this.type === types$1.logicalAND))) { + this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses"); } + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit) } } - this.strict = oldStrict; - this.next(); - node.body = this.finishNode(classBody, "ClassBody"); - this.exitClassBody(); - return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") + return left }; - pp$8.parseClassElement = function(constructorAllowsSuper) { - if (this.eat(types$1.semi)) { return null } - - var ecmaVersion = this.options.ecmaVersion; - var node = this.startNode(); - var keyName = ""; - var isGenerator = false; - var isAsync = false; - var kind = "method"; - var isStatic = false; + pp$5.buildBinary = function(startPos, startLoc, left, right, op, logical) { + if (right.type === "PrivateIdentifier") { this.raise(right.start, "Private identifier can only be left side of binary expression"); } + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.operator = op; + node.right = right; + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") + }; - if (this.eatContextual("static")) { - // Parse static init block - if (ecmaVersion >= 13 && this.eat(types$1.braceL)) { - this.parseClassStaticBlock(node); - return node - } - if (this.isClassElementNameStart() || this.type === types$1.star) { - isStatic = true; - } else { - keyName = "static"; - } - } - node.static = isStatic; - if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) { - if ((this.isClassElementNameStart() || this.type === types$1.star) && !this.canInsertSemicolon()) { - isAsync = true; - } else { - keyName = "async"; - } - } - if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types$1.star)) { - isGenerator = true; - } - if (!keyName && !isAsync && !isGenerator) { - var lastValue = this.value; - if (this.eatContextual("get") || this.eatContextual("set")) { - if (this.isClassElementNameStart()) { - kind = lastValue; - } else { - keyName = lastValue; - } - } - } + // Parse unary operators, both prefix and postfix. - // Parse element name - if (keyName) { - // 'async', 'get', 'set', or 'static' were not a keyword contextually. - // The last token is any of those. Make it the element name. - node.computed = false; - node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc); - node.key.name = keyName; - this.finishNode(node.key, "Identifier"); + pp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forInit) { + var startPos = this.start, startLoc = this.startLoc, expr; + if (this.isContextual("await") && this.canAwait) { + expr = this.parseAwait(forInit); + sawUnary = true; + } else if (this.type.prefix) { + var node = this.startNode(), update = this.type === types$1.incDec; + node.operator = this.value; + node.prefix = true; + this.next(); + node.argument = this.parseMaybeUnary(null, true, update, forInit); + this.checkExpressionErrors(refDestructuringErrors, true); + if (update) { this.checkLValSimple(node.argument); } + else if (this.strict && node.operator === "delete" && + node.argument.type === "Identifier") + { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } + else if (node.operator === "delete" && isPrivateFieldAccess(node.argument)) + { this.raiseRecoverable(node.start, "Private fields can not be deleted"); } + else { sawUnary = true; } + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); + } else if (!sawUnary && this.type === types$1.privateId) { + if (forInit || this.privateNameStack.length === 0) { this.unexpected(); } + expr = this.parsePrivateIdent(); + // only could be private fields in 'in', such as #x in obj + if (this.type !== types$1._in) { this.unexpected(); } } else { - this.parseClassElementName(node); + expr = this.parseExprSubscripts(refDestructuringErrors, forInit); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.operator = this.value; + node$1.prefix = false; + node$1.argument = expr; + this.checkLValSimple(expr); + this.next(); + expr = this.finishNode(node$1, "UpdateExpression"); + } } - // Parse element value - if (ecmaVersion < 13 || this.type === types$1.parenL || kind !== "method" || isGenerator || isAsync) { - var isConstructor = !node.static && checkKeyName(node, "constructor"); - var allowsDirectSuper = isConstructor && constructorAllowsSuper; - // Couldn't move this check into the 'parseClassMethod' method for backward compatibility. - if (isConstructor && kind !== "method") { this.raise(node.key.start, "Constructor can't have get/set modifier"); } - node.kind = isConstructor ? "constructor" : kind; - this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper); + if (!incDec && this.eat(types$1.starstar)) { + if (sawUnary) + { this.unexpected(this.lastTokStart); } + else + { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false, false, forInit), "**", false) } } else { - this.parseClassField(node); + return expr } - - return node }; - pp$8.isClassElementNameStart = function() { + function isPrivateFieldAccess(node) { return ( - this.type === types$1.name || - this.type === types$1.privateId || - this.type === types$1.num || - this.type === types$1.string || - this.type === types$1.bracketL || - this.type.keyword + node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" || + node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) ) - }; + } - pp$8.parseClassElementName = function(element) { - if (this.type === types$1.privateId) { - if (this.value === "constructor") { - this.raise(this.start, "Classes can't have an element named '#constructor'"); - } - element.computed = false; - element.key = this.parsePrivateIdent(); - } else { - this.parsePropertyName(element); + // Parse call, dot, and `[]`-subscript expressions. + + pp$5.parseExprSubscripts = function(refDestructuringErrors, forInit) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprAtom(refDestructuringErrors, forInit); + if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")") + { return expr } + var result = this.parseSubscripts(expr, startPos, startLoc, false, forInit); + if (refDestructuringErrors && result.type === "MemberExpression") { + if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } + if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } + if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; } } + return result }; - pp$8.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) { - // Check key and flags - var key = method.key; - if (method.kind === "constructor") { - if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } - if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } - } else if (method.static && checkKeyName(method, "prototype")) { - this.raise(key.start, "Classes may not have a static property named prototype"); - } + pp$5.parseSubscripts = function(base, startPos, startLoc, noCalls, forInit) { + var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && + this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && + this.potentialArrowAt === base.start; + var optionalChained = false; - // Parse value - var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper); + while (true) { + var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit); - // Check value - if (method.kind === "get" && value.params.length !== 0) - { this.raiseRecoverable(value.start, "getter should have no params"); } - if (method.kind === "set" && value.params.length !== 1) - { this.raiseRecoverable(value.start, "setter should have exactly one param"); } - if (method.kind === "set" && value.params[0].type === "RestElement") - { this.raiseRecoverable(value.params[0].start, "Setter cannot use rest params"); } + if (element.optional) { optionalChained = true; } + if (element === base || element.type === "ArrowFunctionExpression") { + if (optionalChained) { + var chainNode = this.startNodeAt(startPos, startLoc); + chainNode.expression = element; + element = this.finishNode(chainNode, "ChainExpression"); + } + return element + } - return this.finishNode(method, "MethodDefinition") + base = element; + } }; - pp$8.parseClassField = function(field) { - if (checkKeyName(field, "constructor")) { - this.raise(field.key.start, "Classes can't have a field named 'constructor'"); - } else if (field.static && checkKeyName(field, "prototype")) { - this.raise(field.key.start, "Classes can't have a static field named 'prototype'"); - } + pp$5.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) { + var optionalSupported = this.options.ecmaVersion >= 11; + var optional = optionalSupported && this.eat(types$1.questionDot); + if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); } - if (this.eat(types$1.eq)) { - // To raise SyntaxError if 'arguments' exists in the initializer. - var scope = this.currentThisScope(); - var inClassFieldInit = scope.inClassFieldInit; - scope.inClassFieldInit = true; - field.value = this.parseMaybeAssign(); - scope.inClassFieldInit = inClassFieldInit; - } else { - field.value = null; + var computed = this.eat(types$1.bracketL); + if (computed || (optional && this.type !== types$1.parenL && this.type !== types$1.backQuote) || this.eat(types$1.dot)) { + var node = this.startNodeAt(startPos, startLoc); + node.object = base; + if (computed) { + node.property = this.parseExpression(); + this.expect(types$1.bracketR); + } else if (this.type === types$1.privateId && base.type !== "Super") { + node.property = this.parsePrivateIdent(); + } else { + node.property = this.parseIdent(this.options.allowReserved !== "never"); + } + node.computed = !!computed; + if (optionalSupported) { + node.optional = optional; + } + base = this.finishNode(node, "MemberExpression"); + } else if (!noCalls && this.eat(types$1.parenL)) { + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + var exprList = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors); + if (maybeAsyncArrow && !optional && !this.canInsertSemicolon() && this.eat(types$1.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + if (this.awaitIdentPos > 0) + { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); } + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true, forInit) + } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos; + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.callee = base; + node$1.arguments = exprList; + if (optionalSupported) { + node$1.optional = optional; + } + base = this.finishNode(node$1, "CallExpression"); + } else if (this.type === types$1.backQuote) { + if (optional || optionalChained) { + this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions"); + } + var node$2 = this.startNodeAt(startPos, startLoc); + node$2.tag = base; + node$2.quasi = this.parseTemplate({isTagged: true}); + base = this.finishNode(node$2, "TaggedTemplateExpression"); } - this.semicolon(); - - return this.finishNode(field, "PropertyDefinition") + return base }; - pp$8.parseClassStaticBlock = function(node) { - node.body = []; - - var oldLabels = this.labels; - this.labels = []; - this.enterScope(SCOPE_CLASS_STATIC_BLOCK | SCOPE_SUPER); - while (this.type !== types$1.braceR) { - var stmt = this.parseStatement(null); - node.body.push(stmt); - } - this.next(); - this.exitScope(); - this.labels = oldLabels; + // Parse an atomic expression — either a single token that is an + // expression, an expression started by a keyword like `function` or + // `new`, or an expression wrapped in punctuation like `()`, `[]`, + // or `{}`. - return this.finishNode(node, "StaticBlock") - }; + pp$5.parseExprAtom = function(refDestructuringErrors, forInit) { + // If a division operator appears in an expression position, the + // tokenizer got confused, and we force it to read a regexp instead. + if (this.type === types$1.slash) { this.readRegexp(); } - pp$8.parseClassId = function(node, isStatement) { - if (this.type === types$1.name) { - node.id = this.parseIdent(); - if (isStatement) - { this.checkLValSimple(node.id, BIND_LEXICAL, false); } - } else { - if (isStatement === true) + var node, canBeArrow = this.potentialArrowAt === this.start; + switch (this.type) { + case types$1._super: + if (!this.allowSuper) + { this.raise(this.start, "'super' keyword outside a method"); } + node = this.startNode(); + this.next(); + if (this.type === types$1.parenL && !this.allowDirectSuper) + { this.raise(node.start, "super() call outside constructor of a subclass"); } + // The `super` keyword can appear at below: + // SuperProperty: + // super [ Expression ] + // super . IdentifierName + // SuperCall: + // super ( Arguments ) + if (this.type !== types$1.dot && this.type !== types$1.bracketL && this.type !== types$1.parenL) { this.unexpected(); } - node.id = null; - } - }; - - pp$8.parseClassSuper = function(node) { - node.superClass = this.eat(types$1._extends) ? this.parseExprSubscripts(null, false) : null; - }; + return this.finishNode(node, "Super") - pp$8.enterClassBody = function() { - var element = {declared: Object.create(null), used: []}; - this.privateNameStack.push(element); - return element.declared - }; + case types$1._this: + node = this.startNode(); + this.next(); + return this.finishNode(node, "ThisExpression") - pp$8.exitClassBody = function() { - var ref = this.privateNameStack.pop(); - var declared = ref.declared; - var used = ref.used; - var len = this.privateNameStack.length; - var parent = len === 0 ? null : this.privateNameStack[len - 1]; - for (var i = 0; i < used.length; ++i) { - var id = used[i]; - if (!hasOwn(declared, id.name)) { - if (parent) { - parent.used.push(id); - } else { - this.raiseRecoverable(id.start, ("Private field '#" + (id.name) + "' must be declared in an enclosing class")); + case types$1.name: + var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; + var id = this.parseIdent(false); + if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types$1._function)) { + this.overrideContext(types.f_expr); + return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true, forInit) + } + if (canBeArrow && !this.canInsertSemicolon()) { + if (this.eat(types$1.arrow)) + { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false, forInit) } + if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types$1.name && !containsEsc && + (!this.potentialArrowInForAwait || this.value !== "of" || this.containsEsc)) { + id = this.parseIdent(false); + if (this.canInsertSemicolon() || !this.eat(types$1.arrow)) + { this.unexpected(); } + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true, forInit) } } - } - }; + return id - function isPrivateNameConflicted(privateNameMap, element) { - var name = element.key.name; - var curr = privateNameMap[name]; + case types$1.regexp: + var value = this.value; + node = this.parseLiteral(value.value); + node.regex = {pattern: value.pattern, flags: value.flags}; + return node - var next = "true"; - if (element.type === "MethodDefinition" && (element.kind === "get" || element.kind === "set")) { - next = (element.static ? "s" : "i") + element.kind; - } + case types$1.num: case types$1.string: + return this.parseLiteral(this.value) - // `class { get #a(){}; static set #a(_){} }` is also conflict. - if ( - curr === "iget" && next === "iset" || - curr === "iset" && next === "iget" || - curr === "sget" && next === "sset" || - curr === "sset" && next === "sget" - ) { - privateNameMap[name] = "true"; - return false - } else if (!curr) { - privateNameMap[name] = next; - return false - } else { - return true - } - } + case types$1._null: case types$1._true: case types$1._false: + node = this.startNode(); + node.value = this.type === types$1._null ? null : this.type === types$1._true; + node.raw = this.type.keyword; + this.next(); + return this.finishNode(node, "Literal") - function checkKeyName(node, name) { - var computed = node.computed; - var key = node.key; - return !computed && ( - key.type === "Identifier" && key.name === name || - key.type === "Literal" && key.value === name - ) - } + case types$1.parenL: + var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow, forInit); + if (refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) + { refDestructuringErrors.parenthesizedAssign = start; } + if (refDestructuringErrors.parenthesizedBind < 0) + { refDestructuringErrors.parenthesizedBind = start; } + } + return expr - // Parses module export declaration. + case types$1.bracketL: + node = this.startNode(); + this.next(); + node.elements = this.parseExprList(types$1.bracketR, true, true, refDestructuringErrors); + return this.finishNode(node, "ArrayExpression") - pp$8.parseExport = function(node, exports) { - this.next(); - // export * from '...' - if (this.eat(types$1.star)) { + case types$1.braceL: + this.overrideContext(types.b_expr); + return this.parseObj(false, refDestructuringErrors) + + case types$1._function: + node = this.startNode(); + this.next(); + return this.parseFunction(node, 0) + + case types$1._class: + return this.parseClass(this.startNode(), false) + + case types$1._new: + return this.parseNew() + + case types$1.backQuote: + return this.parseTemplate() + + case types$1._import: if (this.options.ecmaVersion >= 11) { - if (this.eatContextual("as")) { - node.exported = this.parseModuleExportName(); - this.checkExport(exports, node.exported, this.lastTokStart); - } else { - node.exported = null; - } - } - this.expectContextual("from"); - if (this.type !== types$1.string) { this.unexpected(); } - node.source = this.parseExprAtom(); - this.semicolon(); - return this.finishNode(node, "ExportAllDeclaration") - } - if (this.eat(types$1._default)) { // export default ... - this.checkExport(exports, "default", this.lastTokStart); - var isAsync; - if (this.type === types$1._function || (isAsync = this.isAsyncFunction())) { - var fNode = this.startNode(); - this.next(); - if (isAsync) { this.next(); } - node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync); - } else if (this.type === types$1._class) { - var cNode = this.startNode(); - node.declaration = this.parseClass(cNode, "nullableID"); + return this.parseExprImport() } else { - node.declaration = this.parseMaybeAssign(); - this.semicolon(); + return this.unexpected() } - return this.finishNode(node, "ExportDefaultDeclaration") + + default: + this.unexpected(); } - // export var|const|let|function|class ... - if (this.shouldParseExportStatement()) { - node.declaration = this.parseStatement(null); - if (node.declaration.type === "VariableDeclaration") - { this.checkVariableExport(exports, node.declaration.declarations); } - else - { this.checkExport(exports, node.declaration.id, node.declaration.id.start); } - node.specifiers = []; - node.source = null; - } else { // export { x, y as z } [from '...'] - node.declaration = null; - node.specifiers = this.parseExportSpecifiers(exports); - if (this.eatContextual("from")) { - if (this.type !== types$1.string) { this.unexpected(); } - node.source = this.parseExprAtom(); - } else { - for (var i = 0, list = node.specifiers; i < list.length; i += 1) { - // check for keywords used as local names - var spec = list[i]; + }; - this.checkUnreserved(spec.local); - // check if export is defined - this.checkLocalExport(spec.local); + pp$5.parseExprImport = function() { + var node = this.startNode(); - if (spec.local.type === "Literal") { - this.raise(spec.local.start, "A string literal cannot be used as an exported binding without `from`."); - } - } + // Consume `import` as an identifier for `import.meta`. + // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`. + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); } + var meta = this.parseIdent(true); - node.source = null; - } - this.semicolon(); + switch (this.type) { + case types$1.parenL: + return this.parseDynamicImport(node) + case types$1.dot: + node.meta = meta; + return this.parseImportMeta(node) + default: + this.unexpected(); } - return this.finishNode(node, "ExportNamedDeclaration") }; - pp$8.checkExport = function(exports, name, pos) { - if (!exports) { return } - if (typeof name !== "string") - { name = name.type === "Identifier" ? name.name : name.value; } - if (hasOwn(exports, name)) - { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); } - exports[name] = true; + pp$5.parseDynamicImport = function(node) { + this.next(); // skip `(` + + // Parse node.source. + node.source = this.parseMaybeAssign(); + + // Verify ending. + if (!this.eat(types$1.parenR)) { + var errorPos = this.start; + if (this.eat(types$1.comma) && this.eat(types$1.parenR)) { + this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()"); + } else { + this.unexpected(errorPos); + } + } + + return this.finishNode(node, "ImportExpression") }; - pp$8.checkPatternExport = function(exports, pat) { - var type = pat.type; - if (type === "Identifier") - { this.checkExport(exports, pat, pat.start); } - else if (type === "ObjectPattern") - { for (var i = 0, list = pat.properties; i < list.length; i += 1) - { - var prop = list[i]; + pp$5.parseImportMeta = function(node) { + this.next(); // skip `.` - this.checkPatternExport(exports, prop); - } } - else if (type === "ArrayPattern") - { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) { - var elt = list$1[i$1]; + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); - if (elt) { this.checkPatternExport(exports, elt); } - } } - else if (type === "Property") - { this.checkPatternExport(exports, pat.value); } - else if (type === "AssignmentPattern") - { this.checkPatternExport(exports, pat.left); } - else if (type === "RestElement") - { this.checkPatternExport(exports, pat.argument); } - else if (type === "ParenthesizedExpression") - { this.checkPatternExport(exports, pat.expression); } + if (node.property.name !== "meta") + { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); } + if (this.options.sourceType !== "module" && !this.options.allowImportExportEverywhere) + { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); } + + return this.finishNode(node, "MetaProperty") }; - pp$8.checkVariableExport = function(exports, decls) { - if (!exports) { return } - for (var i = 0, list = decls; i < list.length; i += 1) - { - var decl = list[i]; + pp$5.parseLiteral = function(value) { + var node = this.startNode(); + node.value = value; + node.raw = this.input.slice(this.start, this.end); + if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1).replace(/_/g, ""); } + this.next(); + return this.finishNode(node, "Literal") + }; - this.checkPatternExport(exports, decl.id); + pp$5.parseParenExpression = function() { + this.expect(types$1.parenL); + var val = this.parseExpression(); + this.expect(types$1.parenR); + return val + }; + + pp$5.parseParenAndDistinguishExpression = function(canBeArrow, forInit) { + var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8; + if (this.options.ecmaVersion >= 6) { + this.next(); + + var innerStartPos = this.start, innerStartLoc = this.startLoc; + var exprList = [], first = true, lastIsComma = false; + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart; + this.yieldPos = 0; + this.awaitPos = 0; + // Do not save awaitIdentPos to allow checking awaits nested in parameters + while (this.type !== types$1.parenR) { + first ? first = false : this.expect(types$1.comma); + if (allowTrailingComma && this.afterTrailingComma(types$1.parenR, true)) { + lastIsComma = true; + break + } else if (this.type === types$1.ellipsis) { + spreadStart = this.start; + exprList.push(this.parseParenItem(this.parseRestBinding())); + if (this.type === types$1.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); } + break + } else { + exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem)); + } + } + var innerEndPos = this.lastTokEnd, innerEndLoc = this.lastTokEndLoc; + this.expect(types$1.parenR); + + if (canBeArrow && !this.canInsertSemicolon() && this.eat(types$1.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + return this.parseParenArrowList(startPos, startLoc, exprList, forInit) + } + + if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); } + if (spreadStart) { this.unexpected(spreadStart); } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc); + val.expressions = exprList; + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); + } else { + val = exprList[0]; + } + } else { + val = this.parseParenExpression(); + } + + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc); + par.expression = val; + return this.finishNode(par, "ParenthesizedExpression") + } else { + return val } }; - pp$8.shouldParseExportStatement = function() { - return this.type.keyword === "var" || - this.type.keyword === "const" || - this.type.keyword === "class" || - this.type.keyword === "function" || - this.isLet() || - this.isAsyncFunction() + pp$5.parseParenItem = function(item) { + return item }; - // Parses a comma-separated list of module exports. + pp$5.parseParenArrowList = function(startPos, startLoc, exprList, forInit) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, false, forInit) + }; - pp$8.parseExportSpecifiers = function(exports) { - var nodes = [], first = true; - // export { x, y as z } [from '...'] - this.expect(types$1.braceL); - while (!this.eat(types$1.braceR)) { - if (!first) { - this.expect(types$1.comma); - if (this.afterTrailingComma(types$1.braceR)) { break } - } else { first = false; } + // New's precedence is slightly tricky. It must allow its argument to + // be a `[]` or dot subscript expression, but not a call — at least, + // not without wrapping it in parentheses. Thus, it uses the noCalls + // argument to parseSubscripts to prevent it from consuming the + // argument list. - var node = this.startNode(); - node.local = this.parseModuleExportName(); - node.exported = this.eatContextual("as") ? this.parseModuleExportName() : node.local; - this.checkExport( - exports, - node.exported, - node.exported.start - ); - nodes.push(this.finishNode(node, "ExportSpecifier")); + var empty = []; + + pp$5.parseNew = function() { + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); } + var node = this.startNode(); + var meta = this.parseIdent(true); + if (this.options.ecmaVersion >= 6 && this.eat(types$1.dot)) { + node.meta = meta; + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + if (node.property.name !== "target") + { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); } + if (!this.allowNewDotTarget) + { this.raiseRecoverable(node.start, "'new.target' can only be used in functions and class static block"); } + return this.finishNode(node, "MetaProperty") } - return nodes + var startPos = this.start, startLoc = this.startLoc, isImport = this.type === types$1._import; + node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true, false); + if (isImport && node.callee.type === "ImportExpression") { + this.raise(startPos, "Cannot use new with import()"); + } + if (this.eat(types$1.parenL)) { node.arguments = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false); } + else { node.arguments = empty; } + return this.finishNode(node, "NewExpression") }; - // Parses import declaration. + // Parse template expression. - pp$8.parseImport = function(node) { - this.next(); - // import '...' - if (this.type === types$1.string) { - node.specifiers = empty$1; - node.source = this.parseExprAtom(); + pp$5.parseTemplateElement = function(ref) { + var isTagged = ref.isTagged; + + var elem = this.startNode(); + if (this.type === types$1.invalidTemplate) { + if (!isTagged) { + this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); + } + elem.value = { + raw: this.value, + cooked: null + }; } else { - node.specifiers = this.parseImportSpecifiers(); - this.expectContextual("from"); - node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected(); + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"), + cooked: this.value + }; } - this.semicolon(); - return this.finishNode(node, "ImportDeclaration") + this.next(); + elem.tail = this.type === types$1.backQuote; + return this.finishNode(elem, "TemplateElement") }; - // Parses a comma-separated list of module imports. + pp$5.parseTemplate = function(ref) { + if ( ref === void 0 ) ref = {}; + var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false; - pp$8.parseImportSpecifiers = function() { - var nodes = [], first = true; - if (this.type === types$1.name) { - // import defaultObj, { x, y as z } from '...' - var node = this.startNode(); - node.local = this.parseIdent(); - this.checkLValSimple(node.local, BIND_LEXICAL); - nodes.push(this.finishNode(node, "ImportDefaultSpecifier")); - if (!this.eat(types$1.comma)) { return nodes } - } - if (this.type === types$1.star) { - var node$1 = this.startNode(); - this.next(); - this.expectContextual("as"); - node$1.local = this.parseIdent(); - this.checkLValSimple(node$1.local, BIND_LEXICAL); - nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); - return nodes + var node = this.startNode(); + this.next(); + node.expressions = []; + var curElt = this.parseTemplateElement({isTagged: isTagged}); + node.quasis = [curElt]; + while (!curElt.tail) { + if (this.type === types$1.eof) { this.raise(this.pos, "Unterminated template literal"); } + this.expect(types$1.dollarBraceL); + node.expressions.push(this.parseExpression()); + this.expect(types$1.braceR); + node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged})); } - this.expect(types$1.braceL); + this.next(); + return this.finishNode(node, "TemplateLiteral") + }; + + pp$5.isAsyncProp = function(prop) { + return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && + (this.type === types$1.name || this.type === types$1.num || this.type === types$1.string || this.type === types$1.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types$1.star)) && + !lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + }; + + // Parse an object literal or binding pattern. + + pp$5.parseObj = function(isPattern, refDestructuringErrors) { + var node = this.startNode(), first = true, propHash = {}; + node.properties = []; + this.next(); while (!this.eat(types$1.braceR)) { if (!first) { this.expect(types$1.comma); - if (this.afterTrailingComma(types$1.braceR)) { break } + if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types$1.braceR)) { break } } else { first = false; } - var node$2 = this.startNode(); - node$2.imported = this.parseModuleExportName(); - if (this.eatContextual("as")) { - node$2.local = this.parseIdent(); - } else { - this.checkUnreserved(node$2.imported); - node$2.local = node$2.imported; - } - this.checkLValSimple(node$2.local, BIND_LEXICAL); - nodes.push(this.finishNode(node$2, "ImportSpecifier")); + var prop = this.parseProperty(isPattern, refDestructuringErrors); + if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); } + node.properties.push(prop); } - return nodes + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") }; - pp$8.parseModuleExportName = function() { - if (this.options.ecmaVersion >= 13 && this.type === types$1.string) { - var stringLiteral = this.parseLiteral(this.value); - if (loneSurrogate.test(stringLiteral.value)) { - this.raise(stringLiteral.start, "An export name cannot include a lone surrogate."); + pp$5.parseProperty = function(isPattern, refDestructuringErrors) { + var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; + if (this.options.ecmaVersion >= 9 && this.eat(types$1.ellipsis)) { + if (isPattern) { + prop.argument = this.parseIdent(false); + if (this.type === types$1.comma) { + this.raise(this.start, "Comma is not permitted after the rest element"); + } + return this.finishNode(prop, "RestElement") } - return stringLiteral + // Parse argument. + prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); + // To disallow trailing comma via `this.toAssignable()`. + if (this.type === types$1.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { + refDestructuringErrors.trailingComma = this.start; + } + // Finish + return this.finishNode(prop, "SpreadElement") } - return this.parseIdent(true) - }; - - // Set `ExpressionStatement#directive` property for directive prologues. - pp$8.adaptDirectivePrologue = function(statements) { - for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { - statements[i].directive = statements[i].expression.raw.slice(1, -1); + if (this.options.ecmaVersion >= 6) { + prop.method = false; + prop.shorthand = false; + if (isPattern || refDestructuringErrors) { + startPos = this.start; + startLoc = this.startLoc; + } + if (!isPattern) + { isGenerator = this.eat(types$1.star); } + } + var containsEsc = this.containsEsc; + this.parsePropertyName(prop); + if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(types$1.star); + this.parsePropertyName(prop); + } else { + isAsync = false; } - }; - pp$8.isDirectiveCandidate = function(statement) { - return ( - this.options.ecmaVersion >= 5 && - statement.type === "ExpressionStatement" && - statement.expression.type === "Literal" && - typeof statement.expression.value === "string" && - // Reject parenthesized strings. - (this.input[statement.start] === "\"" || this.input[statement.start] === "'") - ) + this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); + return this.finishNode(prop, "Property") }; - var pp$7 = Parser.prototype; + pp$5.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { + if ((isGenerator || isAsync) && this.type === types$1.colon) + { this.unexpected(); } - // Convert existing expression atom to assignable pattern - // if possible. + if (this.eat(types$1.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors); + prop.kind = "init"; + } else if (this.options.ecmaVersion >= 6 && this.type === types$1.parenL) { + if (isPattern) { this.unexpected(); } + prop.kind = "init"; + prop.method = true; + prop.value = this.parseMethod(isGenerator, isAsync); + } else if (!isPattern && !containsEsc && + this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type !== types$1.comma && this.type !== types$1.braceR && this.type !== types$1.eq)) { + if (isGenerator || isAsync) { this.unexpected(); } + prop.kind = prop.key.name; + this.parsePropertyName(prop); + prop.value = this.parseMethod(false); + var paramCount = prop.kind === "get" ? 0 : 1; + if (prop.value.params.length !== paramCount) { + var start = prop.value.start; + if (prop.kind === "get") + { this.raiseRecoverable(start, "getter should have no params"); } + else + { this.raiseRecoverable(start, "setter should have exactly one param"); } + } else { + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); } + } + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + if (isGenerator || isAsync) { this.unexpected(); } + this.checkUnreserved(prop.key); + if (prop.key.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = startPos; } + prop.kind = "init"; + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); + } else if (this.type === types$1.eq && refDestructuringErrors) { + if (refDestructuringErrors.shorthandAssign < 0) + { refDestructuringErrors.shorthandAssign = this.start; } + prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); + } else { + prop.value = this.copyNode(prop.key); + } + prop.shorthand = true; + } else { this.unexpected(); } + }; - pp$7.toAssignable = function(node, isBinding, refDestructuringErrors) { - if (this.options.ecmaVersion >= 6 && node) { - switch (node.type) { - case "Identifier": - if (this.inAsync && node.name === "await") - { this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); } - break + pp$5.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(types$1.bracketL)) { + prop.computed = true; + prop.key = this.parseMaybeAssign(); + this.expect(types$1.bracketR); + return prop.key + } else { + prop.computed = false; + } + } + return prop.key = this.type === types$1.num || this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never") + }; - case "ObjectPattern": - case "ArrayPattern": - case "AssignmentPattern": - case "RestElement": - break + // Initialize empty function node. - case "ObjectExpression": - node.type = "ObjectPattern"; - if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } - for (var i = 0, list = node.properties; i < list.length; i += 1) { - var prop = list[i]; + pp$5.initFunction = function(node) { + node.id = null; + if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; } + if (this.options.ecmaVersion >= 8) { node.async = false; } + }; - this.toAssignable(prop, isBinding); - // Early error: - // AssignmentRestProperty[Yield, Await] : - // `...` DestructuringAssignmentTarget[Yield, Await] - // - // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. - if ( - prop.type === "RestElement" && - (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") - ) { - this.raise(prop.argument.start, "Unexpected token"); - } - } - break + // Parse object or class method. - case "Property": - // AssignmentProperty has type === "Property" - if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } - this.toAssignable(node.value, isBinding); - break + pp$5.parseMethod = function(isGenerator, isAsync, allowDirectSuper) { + var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; - case "ArrayExpression": - node.type = "ArrayPattern"; - if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } - this.toAssignableList(node.elements, isBinding); - break + this.initFunction(node); + if (this.options.ecmaVersion >= 6) + { node.generator = isGenerator; } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } - case "SpreadElement": - node.type = "RestElement"; - this.toAssignable(node.argument, isBinding); - if (node.argument.type === "AssignmentPattern") - { this.raise(node.argument.start, "Rest elements cannot have a default value"); } - break + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0)); - case "AssignmentExpression": - if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); } - node.type = "AssignmentPattern"; - delete node.operator; - this.toAssignable(node.left, isBinding); - break + this.expect(types$1.parenL); + node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + this.parseFunctionBody(node, false, true, false); - case "ParenthesizedExpression": - this.toAssignable(node.expression, isBinding, refDestructuringErrors); - break + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "FunctionExpression") + }; - case "ChainExpression": - this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side"); - break + // Parse arrow function expression with given parameters. - case "MemberExpression": - if (!isBinding) { break } + pp$5.parseArrowExpression = function(node, params, isAsync, forInit) { + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; - default: - this.raise(node.start, "Assigning to rvalue"); - } - } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } - return node - }; + this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW); + this.initFunction(node); + if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; } - // Convert list of expression atoms to binding list. + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; - pp$7.toAssignableList = function(exprList, isBinding) { - var end = exprList.length; - for (var i = 0; i < end; i++) { - var elt = exprList[i]; - if (elt) { this.toAssignable(elt, isBinding); } - } - if (end) { - var last = exprList[end - 1]; - if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") - { this.unexpected(last.argument.start); } - } - return exprList + node.params = this.toAssignableList(params, true); + this.parseFunctionBody(node, true, false, forInit); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "ArrowFunctionExpression") }; - // Parses spread element. + // Parse function body and check parameters. - pp$7.parseSpread = function(refDestructuringErrors) { - var node = this.startNode(); - this.next(); - node.argument = this.parseMaybeAssign(false, refDestructuringErrors); - return this.finishNode(node, "SpreadElement") - }; + pp$5.parseFunctionBody = function(node, isArrowFunction, isMethod, forInit) { + var isExpression = isArrowFunction && this.type !== types$1.braceL; + var oldStrict = this.strict, useStrict = false; - pp$7.parseRestBinding = function() { - var node = this.startNode(); - this.next(); + if (isExpression) { + node.body = this.parseMaybeAssign(forInit); + node.expression = true; + this.checkParams(node, false); + } else { + var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params); + if (!oldStrict || nonSimple) { + useStrict = this.strictDirective(this.end); + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + if (useStrict && nonSimple) + { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } + } + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldLabels = this.labels; + this.labels = []; + if (useStrict) { this.strict = true; } - // RestElement inside of a function parameter must be an identifier - if (this.options.ecmaVersion === 6 && this.type !== types$1.name) - { this.unexpected(); } + // Add the params to varDeclaredNames to ensure that an error is thrown + // if a let/const declaration in the function clashes with one of the params. + this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params)); + // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' + if (this.strict && node.id) { this.checkLValSimple(node.id, BIND_OUTSIDE); } + node.body = this.parseBlock(false, undefined, useStrict && !oldStrict); + node.expression = false; + this.adaptDirectivePrologue(node.body.body); + this.labels = oldLabels; + } + this.exitScope(); + }; - node.argument = this.parseBindingAtom(); + pp$5.isSimpleParamList = function(params) { + for (var i = 0, list = params; i < list.length; i += 1) + { + var param = list[i]; - return this.finishNode(node, "RestElement") + if (param.type !== "Identifier") { return false + } } + return true }; - // Parses lvalue (assignable) atom. + // Checks function params for various disallowed patterns such as using "eval" + // or "arguments" and duplicate parameters. - pp$7.parseBindingAtom = function() { - if (this.options.ecmaVersion >= 6) { - switch (this.type) { - case types$1.bracketL: - var node = this.startNode(); - this.next(); - node.elements = this.parseBindingList(types$1.bracketR, true, true); - return this.finishNode(node, "ArrayPattern") + pp$5.checkParams = function(node, allowDuplicates) { + var nameHash = Object.create(null); + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; - case types$1.braceL: - return this.parseObj(true) - } + this.checkLValInnerPattern(param, BIND_VAR, allowDuplicates ? null : nameHash); } - return this.parseIdent() }; - pp$7.parseBindingList = function(close, allowEmpty, allowTrailingComma) { + // Parses a comma-separated list of expressions, and returns them as + // an array. `close` is the token type that ends the list, and + // `allowEmpty` can be turned on to allow subsequent commas with + // nothing in between them to be parsed as `null` (which is needed + // for array literals). + + pp$5.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { var elts = [], first = true; while (!this.eat(close)) { - if (first) { first = false; } - else { this.expect(types$1.comma); } - if (allowEmpty && this.type === types$1.comma) { - elts.push(null); - } else if (allowTrailingComma && this.afterTrailingComma(close)) { - break - } else if (this.type === types$1.ellipsis) { - var rest = this.parseRestBinding(); - this.parseBindingListItem(rest); - elts.push(rest); - if (this.type === types$1.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); } - this.expect(close); - break + if (!first) { + this.expect(types$1.comma); + if (allowTrailingComma && this.afterTrailingComma(close)) { break } + } else { first = false; } + + var elt = (void 0); + if (allowEmpty && this.type === types$1.comma) + { elt = null; } + else if (this.type === types$1.ellipsis) { + elt = this.parseSpread(refDestructuringErrors); + if (refDestructuringErrors && this.type === types$1.comma && refDestructuringErrors.trailingComma < 0) + { refDestructuringErrors.trailingComma = this.start; } } else { - var elem = this.parseMaybeDefault(this.start, this.startLoc); - this.parseBindingListItem(elem); - elts.push(elem); + elt = this.parseMaybeAssign(false, refDestructuringErrors); } + elts.push(elt); } return elts }; - pp$7.parseBindingListItem = function(param) { - return param - }; - - // Parses assignment pattern around given atom if possible. + pp$5.checkUnreserved = function(ref) { + var start = ref.start; + var end = ref.end; + var name = ref.name; - pp$7.parseMaybeDefault = function(startPos, startLoc, left) { - left = left || this.parseBindingAtom(); - if (this.options.ecmaVersion < 6 || !this.eat(types$1.eq)) { return left } - var node = this.startNodeAt(startPos, startLoc); - node.left = left; - node.right = this.parseMaybeAssign(); - return this.finishNode(node, "AssignmentPattern") + if (this.inGenerator && name === "yield") + { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); } + if (this.inAsync && name === "await") + { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); } + if (this.currentThisScope().inClassFieldInit && name === "arguments") + { this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer"); } + if (this.inClassStaticBlock && (name === "arguments" || name === "await")) + { this.raise(start, ("Cannot use " + name + " in class static initialization block")); } + if (this.keywords.test(name)) + { this.raise(start, ("Unexpected keyword '" + name + "'")); } + if (this.options.ecmaVersion < 6 && + this.input.slice(start, end).indexOf("\\") !== -1) { return } + var re = this.strict ? this.reservedWordsStrict : this.reservedWords; + if (re.test(name)) { + if (!this.inAsync && name === "await") + { this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); } + this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); + } }; - // The following three functions all verify that a node is an lvalue — - // something that can be bound, or assigned to. In order to do so, they perform - // a variety of checks: - // - // - Check that none of the bound/assigned-to identifiers are reserved words. - // - Record name declarations for bindings in the appropriate scope. - // - Check duplicate argument names, if checkClashes is set. - // - // If a complex binding pattern is encountered (e.g., object and array - // destructuring), the entire pattern is recursively checked. - // - // There are three versions of checkLVal*() appropriate for different - // circumstances: - // - // - checkLValSimple() shall be used if the syntactic construct supports - // nothing other than identifiers and member expressions. Parenthesized - // expressions are also correctly handled. This is generally appropriate for - // constructs for which the spec says - // - // > It is a Syntax Error if AssignmentTargetType of [the production] is not - // > simple. - // - // It is also appropriate for checking if an identifier is valid and not - // defined elsewhere, like import declarations or function/class identifiers. - // - // Examples where this is used include: - // a += …; - // import a from '…'; - // where a is the node to be checked. - // - // - checkLValPattern() shall be used if the syntactic construct supports - // anything checkLValSimple() supports, as well as object and array - // destructuring patterns. This is generally appropriate for constructs for - // which the spec says - // - // > It is a Syntax Error if [the production] is neither an ObjectLiteral nor - // > an ArrayLiteral and AssignmentTargetType of [the production] is not - // > simple. - // - // Examples where this is used include: - // (a = …); - // const a = …; - // try { … } catch (a) { … } - // where a is the node to be checked. - // - // - checkLValInnerPattern() shall be used if the syntactic construct supports - // anything checkLValPattern() supports, as well as default assignment - // patterns, rest elements, and other constructs that may appear within an - // object or array destructuring pattern. - // - // As a special case, function parameters also use checkLValInnerPattern(), - // as they also support defaults and rest constructs. - // - // These functions deliberately support both assignment and binding constructs, - // as the logic for both is exceedingly similar. If the node is the target of - // an assignment, then bindingType should be set to BIND_NONE. Otherwise, it - // should be set to the appropriate BIND_* constant, like BIND_VAR or - // BIND_LEXICAL. - // - // If the function is called with a non-BIND_NONE bindingType, then - // additionally a checkClashes object may be specified to allow checking for - // duplicate argument names. checkClashes is ignored if the provided construct - // is an assignment (i.e., bindingType is BIND_NONE). - - pp$7.checkLValSimple = function(expr, bindingType, checkClashes) { - if ( bindingType === void 0 ) bindingType = BIND_NONE; + // Parse the next token as an identifier. If `liberal` is true (used + // when parsing properties), it will also convert keywords into + // identifiers. - var isBind = bindingType !== BIND_NONE; + pp$5.parseIdent = function(liberal) { + var node = this.startNode(); + if (this.type === types$1.name) { + node.name = this.value; + } else if (this.type.keyword) { + node.name = this.type.keyword; - switch (expr.type) { - case "Identifier": - if (this.strict && this.reservedWordsStrictBind.test(expr.name)) - { this.raiseRecoverable(expr.start, (isBind ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } - if (isBind) { - if (bindingType === BIND_LEXICAL && expr.name === "let") - { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); } - if (checkClashes) { - if (hasOwn(checkClashes, expr.name)) - { this.raiseRecoverable(expr.start, "Argument name clash"); } - checkClashes[expr.name] = true; - } - if (bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); } + // To fix https://github.com/acornjs/acorn/issues/575 + // `class` and `function` keywords push new context into this.context. + // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. + // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword + if ((node.name === "class" || node.name === "function") && + (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { + this.context.pop(); } - break - - case "ChainExpression": - this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side"); - break - - case "MemberExpression": - if (isBind) { this.raiseRecoverable(expr.start, "Binding member expression"); } - break - - case "ParenthesizedExpression": - if (isBind) { this.raiseRecoverable(expr.start, "Binding parenthesized expression"); } - return this.checkLValSimple(expr.expression, bindingType, checkClashes) - - default: - this.raise(expr.start, (isBind ? "Binding" : "Assigning to") + " rvalue"); + } else { + this.unexpected(); + } + this.next(!!liberal); + this.finishNode(node, "Identifier"); + if (!liberal) { + this.checkUnreserved(node); + if (node.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = node.start; } } + return node }; - pp$7.checkLValPattern = function(expr, bindingType, checkClashes) { - if ( bindingType === void 0 ) bindingType = BIND_NONE; + pp$5.parsePrivateIdent = function() { + var node = this.startNode(); + if (this.type === types$1.privateId) { + node.name = this.value; + } else { + this.unexpected(); + } + this.next(); + this.finishNode(node, "PrivateIdentifier"); - switch (expr.type) { - case "ObjectPattern": - for (var i = 0, list = expr.properties; i < list.length; i += 1) { - var prop = list[i]; + // For validating existence + if (this.privateNameStack.length === 0) { + this.raise(node.start, ("Private field '#" + (node.name) + "' must be declared in an enclosing class")); + } else { + this.privateNameStack[this.privateNameStack.length - 1].used.push(node); + } - this.checkLValInnerPattern(prop, bindingType, checkClashes); - } - break + return node + }; - case "ArrayPattern": - for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { - var elem = list$1[i$1]; + // Parses yield expression inside generator. - if (elem) { this.checkLValInnerPattern(elem, bindingType, checkClashes); } - } - break + pp$5.parseYield = function(forInit) { + if (!this.yieldPos) { this.yieldPos = this.start; } - default: - this.checkLValSimple(expr, bindingType, checkClashes); + var node = this.startNode(); + this.next(); + if (this.type === types$1.semi || this.canInsertSemicolon() || (this.type !== types$1.star && !this.type.startsExpr)) { + node.delegate = false; + node.argument = null; + } else { + node.delegate = this.eat(types$1.star); + node.argument = this.parseMaybeAssign(forInit); } + return this.finishNode(node, "YieldExpression") }; - pp$7.checkLValInnerPattern = function(expr, bindingType, checkClashes) { - if ( bindingType === void 0 ) bindingType = BIND_NONE; - - switch (expr.type) { - case "Property": - // AssignmentProperty has type === "Property" - this.checkLValInnerPattern(expr.value, bindingType, checkClashes); - break + pp$5.parseAwait = function(forInit) { + if (!this.awaitPos) { this.awaitPos = this.start; } - case "AssignmentPattern": - this.checkLValPattern(expr.left, bindingType, checkClashes); - break + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeUnary(null, true, false, forInit); + return this.finishNode(node, "AwaitExpression") + }; - case "RestElement": - this.checkLValPattern(expr.argument, bindingType, checkClashes); - break + var pp$4 = Parser.prototype; - default: - this.checkLValPattern(expr, bindingType, checkClashes); - } + // This function is used to raise exceptions on parse errors. It + // takes an offset integer (into the current `input`) to indicate + // the location of the error, attaches the position to the end + // of the error message, and then raises a `SyntaxError` with that + // message. + + pp$4.raise = function(pos, message) { + var loc = getLineInfo(this.input, pos); + message += " (" + loc.line + ":" + loc.column + ")"; + var err = new SyntaxError(message); + err.pos = pos; err.loc = loc; err.raisedAt = this.pos; + throw err }; - // The algorithm used to determine whether a regexp can appear at a + pp$4.raiseRecoverable = pp$4.raise; - var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { - this.token = token; - this.isExpr = !!isExpr; - this.preserveSpace = !!preserveSpace; - this.override = override; - this.generator = !!generator; + pp$4.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } }; - var types = { - b_stat: new TokContext("{", false), - b_expr: new TokContext("{", true), - b_tmpl: new TokContext("${", false), - p_stat: new TokContext("(", false), - p_expr: new TokContext("(", true), - q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }), - f_stat: new TokContext("function", false), - f_expr: new TokContext("function", true), - f_expr_gen: new TokContext("function", true, false, null, true), - f_gen: new TokContext("function", false, false, null, true) + var pp$3 = Parser.prototype; + + var Scope = function Scope(flags) { + this.flags = flags; + // A list of var-declared names in the current lexical scope + this.var = []; + // A list of lexically-declared names in the current lexical scope + this.lexical = []; + // A list of lexically-declared FunctionDeclaration names in the current lexical scope + this.functions = []; + // A switch to disallow the identifier reference 'arguments' + this.inClassFieldInit = false; }; - var pp$6 = Parser.prototype; + // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. - pp$6.initialContext = function() { - return [types.b_stat] + pp$3.enterScope = function(flags) { + this.scopeStack.push(new Scope(flags)); }; - pp$6.curContext = function() { - return this.context[this.context.length - 1] + pp$3.exitScope = function() { + this.scopeStack.pop(); }; - pp$6.braceIsBlock = function(prevType) { - var parent = this.curContext(); - if (parent === types.f_expr || parent === types.f_stat) - { return true } - if (prevType === types$1.colon && (parent === types.b_stat || parent === types.b_expr)) - { return !parent.isExpr } - - // The check for `tt.name && exprAllowed` detects whether we are - // after a `yield` or `of` construct. See the `updateContext` for - // `tt.name`. - if (prevType === types$1._return || prevType === types$1.name && this.exprAllowed) - { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) } - if (prevType === types$1._else || prevType === types$1.semi || prevType === types$1.eof || prevType === types$1.parenR || prevType === types$1.arrow) - { return true } - if (prevType === types$1.braceL) - { return parent === types.b_stat } - if (prevType === types$1._var || prevType === types$1._const || prevType === types$1.name) - { return false } - return !this.exprAllowed + // The spec says: + // > At the top level of a function, or script, function declarations are + // > treated like var declarations rather than like lexical declarations. + pp$3.treatFunctionsAsVarInScope = function(scope) { + return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP) }; - pp$6.inGeneratorContext = function() { - for (var i = this.context.length - 1; i >= 1; i--) { - var context = this.context[i]; - if (context.token === "function") - { return context.generator } + pp$3.declareName = function(name, bindingType, pos) { + var redeclared = false; + if (bindingType === BIND_LEXICAL) { + var scope = this.currentScope(); + redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1; + scope.lexical.push(name); + if (this.inModule && (scope.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + } else if (bindingType === BIND_SIMPLE_CATCH) { + var scope$1 = this.currentScope(); + scope$1.lexical.push(name); + } else if (bindingType === BIND_FUNCTION) { + var scope$2 = this.currentScope(); + if (this.treatFunctionsAsVar) + { redeclared = scope$2.lexical.indexOf(name) > -1; } + else + { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; } + scope$2.functions.push(name); + } else { + for (var i = this.scopeStack.length - 1; i >= 0; --i) { + var scope$3 = this.scopeStack[i]; + if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) || + !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) { + redeclared = true; + break + } + scope$3.var.push(name); + if (this.inModule && (scope$3.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + if (scope$3.flags & SCOPE_VAR) { break } + } } - return false + if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); } }; - pp$6.updateContext = function(prevType) { - var update, type = this.type; - if (type.keyword && prevType === types$1.dot) - { this.exprAllowed = false; } - else if (update = type.updateContext) - { update.call(this, prevType); } - else - { this.exprAllowed = type.beforeExpr; } + pp$3.checkLocalExport = function(id) { + // scope.functions must be empty as Module code is always strict. + if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && + this.scopeStack[0].var.indexOf(id.name) === -1) { + this.undefinedExports[id.name] = id; + } }; - // Used to handle egde cases when token context could not be inferred correctly during tokenization phase + pp$3.currentScope = function() { + return this.scopeStack[this.scopeStack.length - 1] + }; - pp$6.overrideContext = function(tokenCtx) { - if (this.curContext() !== tokenCtx) { - this.context[this.context.length - 1] = tokenCtx; + pp$3.currentVarScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & SCOPE_VAR) { return scope } } }; - // Token-specific context update code - - types$1.parenR.updateContext = types$1.braceR.updateContext = function() { - if (this.context.length === 1) { - this.exprAllowed = true; - return - } - var out = this.context.pop(); - if (out === types.b_stat && this.curContext().token === "function") { - out = this.context.pop(); + // Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`. + pp$3.currentThisScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope } } - this.exprAllowed = !out.isExpr; }; - types$1.braceL.updateContext = function(prevType) { - this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr); - this.exprAllowed = true; + var Node = function Node(parser, pos, loc) { + this.type = ""; + this.start = pos; + this.end = 0; + if (parser.options.locations) + { this.loc = new SourceLocation(parser, loc); } + if (parser.options.directSourceFile) + { this.sourceFile = parser.options.directSourceFile; } + if (parser.options.ranges) + { this.range = [pos, 0]; } }; - types$1.dollarBraceL.updateContext = function() { - this.context.push(types.b_tmpl); - this.exprAllowed = true; - }; + // Start an AST node, attaching a start offset. - types$1.parenL.updateContext = function(prevType) { - var statementParens = prevType === types$1._if || prevType === types$1._for || prevType === types$1._with || prevType === types$1._while; - this.context.push(statementParens ? types.p_stat : types.p_expr); - this.exprAllowed = true; + var pp$2 = Parser.prototype; + + pp$2.startNode = function() { + return new Node(this, this.start, this.startLoc) }; - types$1.incDec.updateContext = function() { - // tokExprAllowed stays unchanged + pp$2.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) }; - types$1._function.updateContext = types$1._class.updateContext = function(prevType) { - if (prevType.beforeExpr && prevType !== types$1._else && - !(prevType === types$1.semi && this.curContext() !== types.p_stat) && - !(prevType === types$1._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) && - !((prevType === types$1.colon || prevType === types$1.braceL) && this.curContext() === types.b_stat)) - { this.context.push(types.f_expr); } - else - { this.context.push(types.f_stat); } - this.exprAllowed = false; + // Finish an AST node, adding `type` and `end` properties. + + function finishNodeAt(node, type, pos, loc) { + node.type = type; + node.end = pos; + if (this.options.locations) + { node.loc.end = loc; } + if (this.options.ranges) + { node.range[1] = pos; } + return node + } + + pp$2.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) }; - types$1.backQuote.updateContext = function() { - if (this.curContext() === types.q_tmpl) - { this.context.pop(); } - else - { this.context.push(types.q_tmpl); } - this.exprAllowed = false; + // Finish node at given position + + pp$2.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) }; - types$1.star.updateContext = function(prevType) { - if (prevType === types$1._function) { - var index = this.context.length - 1; - if (this.context[index] === types.f_expr) - { this.context[index] = types.f_expr_gen; } - else - { this.context[index] = types.f_gen; } - } - this.exprAllowed = true; + pp$2.copyNode = function(node) { + var newNode = new Node(this, node.start, this.startLoc); + for (var prop in node) { newNode[prop] = node[prop]; } + return newNode }; - types$1.name.updateContext = function(prevType) { - var allowed = false; - if (this.options.ecmaVersion >= 6 && prevType !== types$1.dot) { - if (this.value === "of" && !this.exprAllowed || - this.value === "yield" && this.inGeneratorContext()) - { allowed = true; } - } - this.exprAllowed = allowed; + // This file contains Unicode properties extracted from the ECMAScript specification. + // The lists are extracted like so: + // $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText) + + // #table-binary-unicode-properties + var ecma9BinaryProperties = "ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS"; + var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic"; + var ecma11BinaryProperties = ecma10BinaryProperties; + var ecma12BinaryProperties = ecma11BinaryProperties + " EBase EComp EMod EPres ExtPict"; + var ecma13BinaryProperties = ecma12BinaryProperties; + var ecma14BinaryProperties = ecma13BinaryProperties; + + var unicodeBinaryProperties = { + 9: ecma9BinaryProperties, + 10: ecma10BinaryProperties, + 11: ecma11BinaryProperties, + 12: ecma12BinaryProperties, + 13: ecma13BinaryProperties, + 14: ecma14BinaryProperties }; - // A recursive descent parser operates by defining functions for all + // #table-unicode-general-category-values + var unicodeGeneralCategoryValues = "Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu"; - var pp$5 = Parser.prototype; + // #table-unicode-script-values + var ecma9ScriptValues = "Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb"; + var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd"; + var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"; + var ecma12ScriptValues = ecma11ScriptValues + " Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi"; + var ecma13ScriptValues = ecma12ScriptValues + " Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith"; + var ecma14ScriptValues = ecma13ScriptValues + " Kawi Nag_Mundari Nagm"; - // Check if property name clashes with already added. - // Object/class getters and setters are not allowed to clash — - // either with each other or with an init property — and in - // strict mode, init properties are also not allowed to be repeated. + var unicodeScriptValues = { + 9: ecma9ScriptValues, + 10: ecma10ScriptValues, + 11: ecma11ScriptValues, + 12: ecma12ScriptValues, + 13: ecma13ScriptValues, + 14: ecma14ScriptValues + }; - pp$5.checkPropClash = function(prop, propHash, refDestructuringErrors) { - if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") - { return } - if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) - { return } - var key = prop.key; - var name; - switch (key.type) { - case "Identifier": name = key.name; break - case "Literal": name = String(key.value); break - default: return - } - var kind = prop.kind; - if (this.options.ecmaVersion >= 6) { - if (name === "__proto__" && kind === "init") { - if (propHash.proto) { - if (refDestructuringErrors) { - if (refDestructuringErrors.doubleProto < 0) { - refDestructuringErrors.doubleProto = key.start; - } - } else { - this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); - } - } - propHash.proto = true; - } - return - } - name = "$" + name; - var other = propHash[name]; - if (other) { - var redefinition; - if (kind === "init") { - redefinition = this.strict && other.init || other.get || other.set; - } else { - redefinition = other.init || other[kind]; + var data = {}; + function buildUnicodeData(ecmaVersion) { + var d = data[ecmaVersion] = { + binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues), + nonBinary: { + General_Category: wordsRegexp(unicodeGeneralCategoryValues), + Script: wordsRegexp(unicodeScriptValues[ecmaVersion]) } - if (redefinition) - { this.raiseRecoverable(key.start, "Redefinition of property"); } - } else { - other = propHash[name] = { - init: false, - get: false, - set: false - }; - } - other[kind] = true; - }; + }; + d.nonBinary.Script_Extensions = d.nonBinary.Script; - // ### Expression parsing + d.nonBinary.gc = d.nonBinary.General_Category; + d.nonBinary.sc = d.nonBinary.Script; + d.nonBinary.scx = d.nonBinary.Script_Extensions; + } - // These nest, from the most general expression type at the top to - // 'atomic', nondivisible expression types at the bottom. Most of - // the functions will simply let the function(s) below them parse, - // and, *if* the syntactic construct they handle is present, wrap - // the AST node that the inner parser gave them in another node. + for (var i = 0, list = [9, 10, 11, 12, 13, 14]; i < list.length; i += 1) { + var ecmaVersion = list[i]; - // Parse a full expression. The optional arguments are used to - // forbid the `in` operator (in for loops initalization expressions) - // and provide reference for storing '=' operator inside shorthand - // property assignment in contexts where both object expression - // and object pattern might appear (so it's possible to raise - // delayed syntax error at correct position). + buildUnicodeData(ecmaVersion); + } - pp$5.parseExpression = function(forInit, refDestructuringErrors) { - var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseMaybeAssign(forInit, refDestructuringErrors); - if (this.type === types$1.comma) { - var node = this.startNodeAt(startPos, startLoc); - node.expressions = [expr]; - while (this.eat(types$1.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); } - return this.finishNode(node, "SequenceExpression") - } - return expr + var pp$1 = Parser.prototype; + + var RegExpValidationState = function RegExpValidationState(parser) { + this.parser = parser; + this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : ""); + this.unicodeProperties = data[parser.options.ecmaVersion >= 14 ? 14 : parser.options.ecmaVersion]; + this.source = ""; + this.flags = ""; + this.start = 0; + this.switchU = false; + this.switchN = false; + this.pos = 0; + this.lastIntValue = 0; + this.lastStringValue = ""; + this.lastAssertionIsQuantifiable = false; + this.numCapturingParens = 0; + this.maxBackReference = 0; + this.groupNames = []; + this.backReferenceNames = []; }; - // Parse an assignment expression. This includes applications of - // operators like `+=`. + RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { + var unicode = flags.indexOf("u") !== -1; + this.start = start | 0; + this.source = pattern + ""; + this.flags = flags; + this.switchU = unicode && this.parser.options.ecmaVersion >= 6; + this.switchN = unicode && this.parser.options.ecmaVersion >= 9; + }; - pp$5.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) { - if (this.isContextual("yield")) { - if (this.inGenerator) { return this.parseYield(forInit) } - // The tokenizer will assume an expression is allowed after - // `yield`, but this isn't that kind of yield - else { this.exprAllowed = false; } - } + RegExpValidationState.prototype.raise = function raise (message) { + this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message)); + }; - var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldDoubleProto = -1; - if (refDestructuringErrors) { - oldParenAssign = refDestructuringErrors.parenthesizedAssign; - oldTrailingComma = refDestructuringErrors.trailingComma; - oldDoubleProto = refDestructuringErrors.doubleProto; - refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1; - } else { - refDestructuringErrors = new DestructuringErrors; - ownDestructuringErrors = true; - } + // If u flag is given, this returns the code point at the index (it combines a surrogate pair). + // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair). + RegExpValidationState.prototype.at = function at (i, forceU) { + if ( forceU === void 0 ) forceU = false; - var startPos = this.start, startLoc = this.startLoc; - if (this.type === types$1.parenL || this.type === types$1.name) { - this.potentialArrowAt = this.start; - this.potentialArrowInForAwait = forInit === "await"; + var s = this.source; + var l = s.length; + if (i >= l) { + return -1 } - var left = this.parseMaybeConditional(forInit, refDestructuringErrors); - if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } - if (this.type.isAssign) { - var node = this.startNodeAt(startPos, startLoc); - node.operator = this.value; - if (this.type === types$1.eq) - { left = this.toAssignable(left, false, refDestructuringErrors); } - if (!ownDestructuringErrors) { - refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1; - } - if (refDestructuringErrors.shorthandAssign >= left.start) - { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly - if (this.type === types$1.eq) - { this.checkLValPattern(left); } - else - { this.checkLValSimple(left); } - node.left = left; - this.next(); - node.right = this.parseMaybeAssign(forInit); - if (oldDoubleProto > -1) { refDestructuringErrors.doubleProto = oldDoubleProto; } - return this.finishNode(node, "AssignmentExpression") - } else { - if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } + var c = s.charCodeAt(i); + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + return c } - if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; } - if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; } - return left + var next = s.charCodeAt(i + 1); + return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c }; - // Parse a ternary conditional (`?:`) operator. + RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) { + if ( forceU === void 0 ) forceU = false; - pp$5.parseMaybeConditional = function(forInit, refDestructuringErrors) { - var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseExprOps(forInit, refDestructuringErrors); - if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } - if (this.eat(types$1.question)) { - var node = this.startNodeAt(startPos, startLoc); - node.test = expr; - node.consequent = this.parseMaybeAssign(); - this.expect(types$1.colon); - node.alternate = this.parseMaybeAssign(forInit); - return this.finishNode(node, "ConditionalExpression") + var s = this.source; + var l = s.length; + if (i >= l) { + return l } - return expr + var c = s.charCodeAt(i), next; + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l || + (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) { + return i + 1 + } + return i + 2 }; - // Start the precedence parser. + RegExpValidationState.prototype.current = function current (forceU) { + if ( forceU === void 0 ) forceU = false; - pp$5.parseExprOps = function(forInit, refDestructuringErrors) { - var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseMaybeUnary(refDestructuringErrors, false, false, forInit); - if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } - return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit) + return this.at(this.pos, forceU) }; - // Parse binary operators with the operator precedence parsing - // algorithm. `left` is the left-hand side of the operator. - // `minPrec` provides context that allows the function to stop and - // defer further parser to one of its callers when it encounters an - // operator that has a lower precedence than the set it is parsing. - - pp$5.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) { - var prec = this.type.binop; - if (prec != null && (!forInit || this.type !== types$1._in)) { - if (prec > minPrec) { - var logical = this.type === types$1.logicalOR || this.type === types$1.logicalAND; - var coalesce = this.type === types$1.coalesce; - if (coalesce) { - // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions. - // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error. - prec = types$1.logicalAND.binop; - } - var op = this.value; - this.next(); - var startPos = this.start, startLoc = this.startLoc; - var right = this.parseExprOp(this.parseMaybeUnary(null, false, false, forInit), startPos, startLoc, prec, forInit); - var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce); - if ((logical && this.type === types$1.coalesce) || (coalesce && (this.type === types$1.logicalOR || this.type === types$1.logicalAND))) { - this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses"); - } - return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit) - } - } - return left - }; + RegExpValidationState.prototype.lookahead = function lookahead (forceU) { + if ( forceU === void 0 ) forceU = false; - pp$5.buildBinary = function(startPos, startLoc, left, right, op, logical) { - if (right.type === "PrivateIdentifier") { this.raise(right.start, "Private identifier can only be left side of binary expression"); } - var node = this.startNodeAt(startPos, startLoc); - node.left = left; - node.operator = op; - node.right = right; - return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") + return this.at(this.nextIndex(this.pos, forceU), forceU) }; - // Parse unary operators, both prefix and postfix. - - pp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forInit) { - var startPos = this.start, startLoc = this.startLoc, expr; - if (this.isContextual("await") && this.canAwait) { - expr = this.parseAwait(forInit); - sawUnary = true; - } else if (this.type.prefix) { - var node = this.startNode(), update = this.type === types$1.incDec; - node.operator = this.value; - node.prefix = true; - this.next(); - node.argument = this.parseMaybeUnary(null, true, update, forInit); - this.checkExpressionErrors(refDestructuringErrors, true); - if (update) { this.checkLValSimple(node.argument); } - else if (this.strict && node.operator === "delete" && - node.argument.type === "Identifier") - { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } - else if (node.operator === "delete" && isPrivateFieldAccess(node.argument)) - { this.raiseRecoverable(node.start, "Private fields can not be deleted"); } - else { sawUnary = true; } - expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); - } else if (!sawUnary && this.type === types$1.privateId) { - if (forInit || this.privateNameStack.length === 0) { this.unexpected(); } - expr = this.parsePrivateIdent(); - // only could be private fields in 'in', such as #x in obj - if (this.type !== types$1._in) { this.unexpected(); } - } else { - expr = this.parseExprSubscripts(refDestructuringErrors, forInit); - if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } - while (this.type.postfix && !this.canInsertSemicolon()) { - var node$1 = this.startNodeAt(startPos, startLoc); - node$1.operator = this.value; - node$1.prefix = false; - node$1.argument = expr; - this.checkLValSimple(expr); - this.next(); - expr = this.finishNode(node$1, "UpdateExpression"); - } - } + RegExpValidationState.prototype.advance = function advance (forceU) { + if ( forceU === void 0 ) forceU = false; - if (!incDec && this.eat(types$1.starstar)) { - if (sawUnary) - { this.unexpected(this.lastTokStart); } - else - { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false, false, forInit), "**", false) } - } else { - return expr - } + this.pos = this.nextIndex(this.pos, forceU); }; - function isPrivateFieldAccess(node) { - return ( - node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" || - node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) - ) - } - - // Parse call, dot, and `[]`-subscript expressions. + RegExpValidationState.prototype.eat = function eat (ch, forceU) { + if ( forceU === void 0 ) forceU = false; - pp$5.parseExprSubscripts = function(refDestructuringErrors, forInit) { - var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseExprAtom(refDestructuringErrors, forInit); - if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")") - { return expr } - var result = this.parseSubscripts(expr, startPos, startLoc, false, forInit); - if (refDestructuringErrors && result.type === "MemberExpression") { - if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } - if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } - if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; } + if (this.current(forceU) === ch) { + this.advance(forceU); + return true } - return result + return false }; - pp$5.parseSubscripts = function(base, startPos, startLoc, noCalls, forInit) { - var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && - this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && - this.potentialArrowAt === base.start; - var optionalChained = false; - - while (true) { - var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit); + /** + * Validate the flags part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ + pp$1.validateRegExpFlags = function(state) { + var validFlags = state.validFlags; + var flags = state.flags; - if (element.optional) { optionalChained = true; } - if (element === base || element.type === "ArrowFunctionExpression") { - if (optionalChained) { - var chainNode = this.startNodeAt(startPos, startLoc); - chainNode.expression = element; - element = this.finishNode(chainNode, "ChainExpression"); - } - return element + for (var i = 0; i < flags.length; i++) { + var flag = flags.charAt(i); + if (validFlags.indexOf(flag) === -1) { + this.raise(state.start, "Invalid regular expression flag"); + } + if (flags.indexOf(flag, i + 1) > -1) { + this.raise(state.start, "Duplicate regular expression flag"); } - - base = element; } }; - pp$5.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) { - var optionalSupported = this.options.ecmaVersion >= 11; - var optional = optionalSupported && this.eat(types$1.questionDot); - if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); } + /** + * Validate the pattern part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ + pp$1.validateRegExpPattern = function(state) { + this.regexp_pattern(state); - var computed = this.eat(types$1.bracketL); - if (computed || (optional && this.type !== types$1.parenL && this.type !== types$1.backQuote) || this.eat(types$1.dot)) { - var node = this.startNodeAt(startPos, startLoc); - node.object = base; - if (computed) { - node.property = this.parseExpression(); - this.expect(types$1.bracketR); - } else if (this.type === types$1.privateId && base.type !== "Super") { - node.property = this.parsePrivateIdent(); - } else { - node.property = this.parseIdent(this.options.allowReserved !== "never"); - } - node.computed = !!computed; - if (optionalSupported) { - node.optional = optional; - } - base = this.finishNode(node, "MemberExpression"); - } else if (!noCalls && this.eat(types$1.parenL)) { - var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; - this.yieldPos = 0; - this.awaitPos = 0; - this.awaitIdentPos = 0; - var exprList = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors); - if (maybeAsyncArrow && !optional && !this.canInsertSemicolon() && this.eat(types$1.arrow)) { - this.checkPatternErrors(refDestructuringErrors, false); - this.checkYieldAwaitInDefaultParams(); - if (this.awaitIdentPos > 0) - { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); } - this.yieldPos = oldYieldPos; - this.awaitPos = oldAwaitPos; - this.awaitIdentPos = oldAwaitIdentPos; - return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true, forInit) - } - this.checkExpressionErrors(refDestructuringErrors, true); - this.yieldPos = oldYieldPos || this.yieldPos; - this.awaitPos = oldAwaitPos || this.awaitPos; - this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos; - var node$1 = this.startNodeAt(startPos, startLoc); - node$1.callee = base; - node$1.arguments = exprList; - if (optionalSupported) { - node$1.optional = optional; - } - base = this.finishNode(node$1, "CallExpression"); - } else if (this.type === types$1.backQuote) { - if (optional || optionalChained) { - this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions"); - } - var node$2 = this.startNodeAt(startPos, startLoc); - node$2.tag = base; - node$2.quasi = this.parseTemplate({isTagged: true}); - base = this.finishNode(node$2, "TaggedTemplateExpression"); + // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of + // parsing contains a |GroupName|, reparse with the goal symbol + // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* + // exception if _P_ did not conform to the grammar, if any elements of _P_ + // were not matched by the parse, or if any Early Error conditions exist. + if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { + state.switchN = true; + this.regexp_pattern(state); } - return base }; - // Parse an atomic expression — either a single token that is an - // expression, an expression started by a keyword like `function` or - // `new`, or an expression wrapped in punctuation like `()`, `[]`, - // or `{}`. - - pp$5.parseExprAtom = function(refDestructuringErrors, forInit) { - // If a division operator appears in an expression position, the - // tokenizer got confused, and we force it to read a regexp instead. - if (this.type === types$1.slash) { this.readRegexp(); } - - var node, canBeArrow = this.potentialArrowAt === this.start; - switch (this.type) { - case types$1._super: - if (!this.allowSuper) - { this.raise(this.start, "'super' keyword outside a method"); } - node = this.startNode(); - this.next(); - if (this.type === types$1.parenL && !this.allowDirectSuper) - { this.raise(node.start, "super() call outside constructor of a subclass"); } - // The `super` keyword can appear at below: - // SuperProperty: - // super [ Expression ] - // super . IdentifierName - // SuperCall: - // super ( Arguments ) - if (this.type !== types$1.dot && this.type !== types$1.bracketL && this.type !== types$1.parenL) - { this.unexpected(); } - return this.finishNode(node, "Super") + // https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern + pp$1.regexp_pattern = function(state) { + state.pos = 0; + state.lastIntValue = 0; + state.lastStringValue = ""; + state.lastAssertionIsQuantifiable = false; + state.numCapturingParens = 0; + state.maxBackReference = 0; + state.groupNames.length = 0; + state.backReferenceNames.length = 0; - case types$1._this: - node = this.startNode(); - this.next(); - return this.finishNode(node, "ThisExpression") + this.regexp_disjunction(state); - case types$1.name: - var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; - var id = this.parseIdent(false); - if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types$1._function)) { - this.overrideContext(types.f_expr); - return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true, forInit) + if (state.pos !== state.source.length) { + // Make the same messages as V8. + if (state.eat(0x29 /* ) */)) { + state.raise("Unmatched ')'"); } - if (canBeArrow && !this.canInsertSemicolon()) { - if (this.eat(types$1.arrow)) - { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false, forInit) } - if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types$1.name && !containsEsc && - (!this.potentialArrowInForAwait || this.value !== "of" || this.containsEsc)) { - id = this.parseIdent(false); - if (this.canInsertSemicolon() || !this.eat(types$1.arrow)) - { this.unexpected(); } - return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true, forInit) - } + if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) { + state.raise("Lone quantifier brackets"); } - return id - - case types$1.regexp: - var value = this.value; - node = this.parseLiteral(value.value); - node.regex = {pattern: value.pattern, flags: value.flags}; - return node - - case types$1.num: case types$1.string: - return this.parseLiteral(this.value) - - case types$1._null: case types$1._true: case types$1._false: - node = this.startNode(); - node.value = this.type === types$1._null ? null : this.type === types$1._true; - node.raw = this.type.keyword; - this.next(); - return this.finishNode(node, "Literal") + } + if (state.maxBackReference > state.numCapturingParens) { + state.raise("Invalid escape"); + } + for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) { + var name = list[i]; - case types$1.parenL: - var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow, forInit); - if (refDestructuringErrors) { - if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) - { refDestructuringErrors.parenthesizedAssign = start; } - if (refDestructuringErrors.parenthesizedBind < 0) - { refDestructuringErrors.parenthesizedBind = start; } + if (state.groupNames.indexOf(name) === -1) { + state.raise("Invalid named capture referenced"); } - return expr - - case types$1.bracketL: - node = this.startNode(); - this.next(); - node.elements = this.parseExprList(types$1.bracketR, true, true, refDestructuringErrors); - return this.finishNode(node, "ArrayExpression") - - case types$1.braceL: - this.overrideContext(types.b_expr); - return this.parseObj(false, refDestructuringErrors) - - case types$1._function: - node = this.startNode(); - this.next(); - return this.parseFunction(node, 0) + } + }; - case types$1._class: - return this.parseClass(this.startNode(), false) + // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction + pp$1.regexp_disjunction = function(state) { + this.regexp_alternative(state); + while (state.eat(0x7C /* | */)) { + this.regexp_alternative(state); + } - case types$1._new: - return this.parseNew() + // Make the same message as V8. + if (this.regexp_eatQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + if (state.eat(0x7B /* { */)) { + state.raise("Lone quantifier brackets"); + } + }; - case types$1.backQuote: - return this.parseTemplate() + // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative + pp$1.regexp_alternative = function(state) { + while (state.pos < state.source.length && this.regexp_eatTerm(state)) + { } + }; - case types$1._import: - if (this.options.ecmaVersion >= 11) { - return this.parseExprImport() - } else { - return this.unexpected() + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term + pp$1.regexp_eatTerm = function(state) { + if (this.regexp_eatAssertion(state)) { + // Handle `QuantifiableAssertion Quantifier` alternative. + // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion + // is a QuantifiableAssertion. + if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) { + // Make the same message as V8. + if (state.switchU) { + state.raise("Invalid quantifier"); + } } + return true + } - default: - this.unexpected(); + if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { + this.regexp_eatQuantifier(state); + return true } - }; - pp$5.parseExprImport = function() { - var node = this.startNode(); + return false + }; - // Consume `import` as an identifier for `import.meta`. - // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`. - if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); } - var meta = this.parseIdent(true); + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion + pp$1.regexp_eatAssertion = function(state) { + var start = state.pos; + state.lastAssertionIsQuantifiable = false; - switch (this.type) { - case types$1.parenL: - return this.parseDynamicImport(node) - case types$1.dot: - node.meta = meta; - return this.parseImportMeta(node) - default: - this.unexpected(); + // ^, $ + if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) { + return true } - }; - - pp$5.parseDynamicImport = function(node) { - this.next(); // skip `(` - // Parse node.source. - node.source = this.parseMaybeAssign(); + // \b \B + if (state.eat(0x5C /* \ */)) { + if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) { + return true + } + state.pos = start; + } - // Verify ending. - if (!this.eat(types$1.parenR)) { - var errorPos = this.start; - if (this.eat(types$1.comma) && this.eat(types$1.parenR)) { - this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()"); - } else { - this.unexpected(errorPos); + // Lookahead / Lookbehind + if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) { + var lookbehind = false; + if (this.options.ecmaVersion >= 9) { + lookbehind = state.eat(0x3C /* < */); + } + if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) { + this.regexp_disjunction(state); + if (!state.eat(0x29 /* ) */)) { + state.raise("Unterminated group"); + } + state.lastAssertionIsQuantifiable = !lookbehind; + return true } } - return this.finishNode(node, "ImportExpression") + state.pos = start; + return false }; - pp$5.parseImportMeta = function(node) { - this.next(); // skip `.` - - var containsEsc = this.containsEsc; - node.property = this.parseIdent(true); - - if (node.property.name !== "meta") - { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); } - if (containsEsc) - { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); } - if (this.options.sourceType !== "module" && !this.options.allowImportExportEverywhere) - { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); } - - return this.finishNode(node, "MetaProperty") - }; + // https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier + pp$1.regexp_eatQuantifier = function(state, noError) { + if ( noError === void 0 ) noError = false; - pp$5.parseLiteral = function(value) { - var node = this.startNode(); - node.value = value; - node.raw = this.input.slice(this.start, this.end); - if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1).replace(/_/g, ""); } - this.next(); - return this.finishNode(node, "Literal") + if (this.regexp_eatQuantifierPrefix(state, noError)) { + state.eat(0x3F /* ? */); + return true + } + return false }; - pp$5.parseParenExpression = function() { - this.expect(types$1.parenL); - var val = this.parseExpression(); - this.expect(types$1.parenR); - return val + // https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix + pp$1.regexp_eatQuantifierPrefix = function(state, noError) { + return ( + state.eat(0x2A /* * */) || + state.eat(0x2B /* + */) || + state.eat(0x3F /* ? */) || + this.regexp_eatBracedQuantifier(state, noError) + ) }; - - pp$5.parseParenAndDistinguishExpression = function(canBeArrow, forInit) { - var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8; - if (this.options.ecmaVersion >= 6) { - this.next(); - - var innerStartPos = this.start, innerStartLoc = this.startLoc; - var exprList = [], first = true, lastIsComma = false; - var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart; - this.yieldPos = 0; - this.awaitPos = 0; - // Do not save awaitIdentPos to allow checking awaits nested in parameters - while (this.type !== types$1.parenR) { - first ? first = false : this.expect(types$1.comma); - if (allowTrailingComma && this.afterTrailingComma(types$1.parenR, true)) { - lastIsComma = true; - break - } else if (this.type === types$1.ellipsis) { - spreadStart = this.start; - exprList.push(this.parseParenItem(this.parseRestBinding())); - if (this.type === types$1.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); } - break - } else { - exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem)); + pp$1.regexp_eatBracedQuantifier = function(state, noError) { + var start = state.pos; + if (state.eat(0x7B /* { */)) { + var min = 0, max = -1; + if (this.regexp_eatDecimalDigits(state)) { + min = state.lastIntValue; + if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) { + max = state.lastIntValue; + } + if (state.eat(0x7D /* } */)) { + // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term + if (max !== -1 && max < min && !noError) { + state.raise("numbers out of order in {} quantifier"); + } + return true } } - var innerEndPos = this.lastTokEnd, innerEndLoc = this.lastTokEndLoc; - this.expect(types$1.parenR); - - if (canBeArrow && !this.canInsertSemicolon() && this.eat(types$1.arrow)) { - this.checkPatternErrors(refDestructuringErrors, false); - this.checkYieldAwaitInDefaultParams(); - this.yieldPos = oldYieldPos; - this.awaitPos = oldAwaitPos; - return this.parseParenArrowList(startPos, startLoc, exprList, forInit) + if (state.switchU && !noError) { + state.raise("Incomplete quantifier"); } + state.pos = start; + } + return false + }; - if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); } - if (spreadStart) { this.unexpected(spreadStart); } - this.checkExpressionErrors(refDestructuringErrors, true); - this.yieldPos = oldYieldPos || this.yieldPos; - this.awaitPos = oldAwaitPos || this.awaitPos; - - if (exprList.length > 1) { - val = this.startNodeAt(innerStartPos, innerStartLoc); - val.expressions = exprList; - this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); - } else { - val = exprList[0]; + // https://www.ecma-international.org/ecma-262/8.0/#prod-Atom + pp$1.regexp_eatAtom = function(state) { + return ( + this.regexp_eatPatternCharacters(state) || + state.eat(0x2E /* . */) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) + ) + }; + pp$1.regexp_eatReverseSolidusAtomEscape = function(state) { + var start = state.pos; + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatAtomEscape(state)) { + return true } - } else { - val = this.parseParenExpression(); + state.pos = start; } - - if (this.options.preserveParens) { - var par = this.startNodeAt(startPos, startLoc); - par.expression = val; - return this.finishNode(par, "ParenthesizedExpression") - } else { - return val + return false + }; + pp$1.regexp_eatUncapturingGroup = function(state) { + var start = state.pos; + if (state.eat(0x28 /* ( */)) { + if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) { + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + return true + } + state.raise("Unterminated group"); + } + state.pos = start; } + return false }; - - pp$5.parseParenItem = function(item) { - return item + pp$1.regexp_eatCapturingGroup = function(state) { + if (state.eat(0x28 /* ( */)) { + if (this.options.ecmaVersion >= 9) { + this.regexp_groupSpecifier(state); + } else if (state.current() === 0x3F /* ? */) { + state.raise("Invalid group"); + } + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + state.numCapturingParens += 1; + return true + } + state.raise("Unterminated group"); + } + return false }; - pp$5.parseParenArrowList = function(startPos, startLoc, exprList, forInit) { - return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, false, forInit) + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom + pp$1.regexp_eatExtendedAtom = function(state) { + return ( + state.eat(0x2E /* . */) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) || + this.regexp_eatInvalidBracedQuantifier(state) || + this.regexp_eatExtendedPatternCharacter(state) + ) }; - // New's precedence is slightly tricky. It must allow its argument to - // be a `[]` or dot subscript expression, but not a call — at least, - // not without wrapping it in parentheses. Thus, it uses the noCalls - // argument to parseSubscripts to prevent it from consuming the - // argument list. + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier + pp$1.regexp_eatInvalidBracedQuantifier = function(state) { + if (this.regexp_eatBracedQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + return false + }; - var empty = []; + // https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter + pp$1.regexp_eatSyntaxCharacter = function(state) { + var ch = state.current(); + if (isSyntaxCharacter(ch)) { + state.lastIntValue = ch; + state.advance(); + return true + } + return false + }; + function isSyntaxCharacter(ch) { + return ( + ch === 0x24 /* $ */ || + ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ || + ch === 0x2E /* . */ || + ch === 0x3F /* ? */ || + ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ || + ch >= 0x7B /* { */ && ch <= 0x7D /* } */ + ) + } - pp$5.parseNew = function() { - if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); } - var node = this.startNode(); - var meta = this.parseIdent(true); - if (this.options.ecmaVersion >= 6 && this.eat(types$1.dot)) { - node.meta = meta; - var containsEsc = this.containsEsc; - node.property = this.parseIdent(true); - if (node.property.name !== "target") - { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); } - if (containsEsc) - { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); } - if (!this.allowNewDotTarget) - { this.raiseRecoverable(node.start, "'new.target' can only be used in functions and class static block"); } - return this.finishNode(node, "MetaProperty") + // https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter + // But eat eager. + pp$1.regexp_eatPatternCharacters = function(state) { + var start = state.pos; + var ch = 0; + while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) { + state.advance(); } - var startPos = this.start, startLoc = this.startLoc, isImport = this.type === types$1._import; - node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true, false); - if (isImport && node.callee.type === "ImportExpression") { - this.raise(startPos, "Cannot use new with import()"); + return state.pos !== start + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter + pp$1.regexp_eatExtendedPatternCharacter = function(state) { + var ch = state.current(); + if ( + ch !== -1 && + ch !== 0x24 /* $ */ && + !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) && + ch !== 0x2E /* . */ && + ch !== 0x3F /* ? */ && + ch !== 0x5B /* [ */ && + ch !== 0x5E /* ^ */ && + ch !== 0x7C /* | */ + ) { + state.advance(); + return true } - if (this.eat(types$1.parenL)) { node.arguments = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false); } - else { node.arguments = empty; } - return this.finishNode(node, "NewExpression") + return false }; - // Parse template expression. + // GroupSpecifier :: + // [empty] + // `?` GroupName + pp$1.regexp_groupSpecifier = function(state) { + if (state.eat(0x3F /* ? */)) { + if (this.regexp_eatGroupName(state)) { + if (state.groupNames.indexOf(state.lastStringValue) !== -1) { + state.raise("Duplicate capture group name"); + } + state.groupNames.push(state.lastStringValue); + return + } + state.raise("Invalid group"); + } + }; - pp$5.parseTemplateElement = function(ref) { - var isTagged = ref.isTagged; + // GroupName :: + // `<` RegExpIdentifierName `>` + // Note: this updates `state.lastStringValue` property with the eaten name. + pp$1.regexp_eatGroupName = function(state) { + state.lastStringValue = ""; + if (state.eat(0x3C /* < */)) { + if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) { + return true + } + state.raise("Invalid capture group name"); + } + return false + }; - var elem = this.startNode(); - if (this.type === types$1.invalidTemplate) { - if (!isTagged) { - this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); + // RegExpIdentifierName :: + // RegExpIdentifierStart + // RegExpIdentifierName RegExpIdentifierPart + // Note: this updates `state.lastStringValue` property with the eaten name. + pp$1.regexp_eatRegExpIdentifierName = function(state) { + state.lastStringValue = ""; + if (this.regexp_eatRegExpIdentifierStart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); + while (this.regexp_eatRegExpIdentifierPart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); } - elem.value = { - raw: this.value, - cooked: null - }; - } else { - elem.value = { - raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"), - cooked: this.value - }; + return true } - this.next(); - elem.tail = this.type === types$1.backQuote; - return this.finishNode(elem, "TemplateElement") + return false }; - pp$5.parseTemplate = function(ref) { - if ( ref === void 0 ) ref = {}; - var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false; + // RegExpIdentifierStart :: + // UnicodeIDStart + // `$` + // `_` + // `\` RegExpUnicodeEscapeSequence[+U] + pp$1.regexp_eatRegExpIdentifierStart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); - var node = this.startNode(); - this.next(); - node.expressions = []; - var curElt = this.parseTemplateElement({isTagged: isTagged}); - node.quasis = [curElt]; - while (!curElt.tail) { - if (this.type === types$1.eof) { this.raise(this.pos, "Unterminated template literal"); } - this.expect(types$1.dollarBraceL); - node.expressions.push(this.parseExpression()); - this.expect(types$1.braceR); - node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged})); + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + ch = state.lastIntValue; + } + if (isRegExpIdentifierStart(ch)) { + state.lastIntValue = ch; + return true } - this.next(); - return this.finishNode(node, "TemplateLiteral") - }; - pp$5.isAsyncProp = function(prop) { - return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && - (this.type === types$1.name || this.type === types$1.num || this.type === types$1.string || this.type === types$1.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types$1.star)) && - !lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + state.pos = start; + return false }; + function isRegExpIdentifierStart(ch) { + return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ + } - // Parse an object literal or binding pattern. - - pp$5.parseObj = function(isPattern, refDestructuringErrors) { - var node = this.startNode(), first = true, propHash = {}; - node.properties = []; - this.next(); - while (!this.eat(types$1.braceR)) { - if (!first) { - this.expect(types$1.comma); - if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types$1.braceR)) { break } - } else { first = false; } + // RegExpIdentifierPart :: + // UnicodeIDContinue + // `$` + // `_` + // `\` RegExpUnicodeEscapeSequence[+U] + // + // + pp$1.regexp_eatRegExpIdentifierPart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); - var prop = this.parseProperty(isPattern, refDestructuringErrors); - if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); } - node.properties.push(prop); + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + ch = state.lastIntValue; } - return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") + if (isRegExpIdentifierPart(ch)) { + state.lastIntValue = ch; + return true + } + + state.pos = start; + return false }; + function isRegExpIdentifierPart(ch) { + return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* */ || ch === 0x200D /* */ + } - pp$5.parseProperty = function(isPattern, refDestructuringErrors) { - var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; - if (this.options.ecmaVersion >= 9 && this.eat(types$1.ellipsis)) { - if (isPattern) { - prop.argument = this.parseIdent(false); - if (this.type === types$1.comma) { - this.raise(this.start, "Comma is not permitted after the rest element"); + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape + pp$1.regexp_eatAtomEscape = function(state) { + if ( + this.regexp_eatBackReference(state) || + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) || + (state.switchN && this.regexp_eatKGroupName(state)) + ) { + return true + } + if (state.switchU) { + // Make the same message as V8. + if (state.current() === 0x63 /* c */) { + state.raise("Invalid unicode escape"); + } + state.raise("Invalid escape"); + } + return false + }; + pp$1.regexp_eatBackReference = function(state) { + var start = state.pos; + if (this.regexp_eatDecimalEscape(state)) { + var n = state.lastIntValue; + if (state.switchU) { + // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape + if (n > state.maxBackReference) { + state.maxBackReference = n; } - return this.finishNode(prop, "RestElement") + return true } - // Parse argument. - prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); - // To disallow trailing comma via `this.toAssignable()`. - if (this.type === types$1.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { - refDestructuringErrors.trailingComma = this.start; + if (n <= state.numCapturingParens) { + return true } - // Finish - return this.finishNode(prop, "SpreadElement") + state.pos = start; } - if (this.options.ecmaVersion >= 6) { - prop.method = false; - prop.shorthand = false; - if (isPattern || refDestructuringErrors) { - startPos = this.start; - startLoc = this.startLoc; + return false + }; + pp$1.regexp_eatKGroupName = function(state) { + if (state.eat(0x6B /* k */)) { + if (this.regexp_eatGroupName(state)) { + state.backReferenceNames.push(state.lastStringValue); + return true } - if (!isPattern) - { isGenerator = this.eat(types$1.star); } - } - var containsEsc = this.containsEsc; - this.parsePropertyName(prop); - if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { - isAsync = true; - isGenerator = this.options.ecmaVersion >= 9 && this.eat(types$1.star); - this.parsePropertyName(prop); - } else { - isAsync = false; + state.raise("Invalid named reference"); } - this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); - return this.finishNode(prop, "Property") + return false }; - pp$5.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { - if ((isGenerator || isAsync) && this.type === types$1.colon) - { this.unexpected(); } - - if (this.eat(types$1.colon)) { - prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors); - prop.kind = "init"; - } else if (this.options.ecmaVersion >= 6 && this.type === types$1.parenL) { - if (isPattern) { this.unexpected(); } - prop.kind = "init"; - prop.method = true; - prop.value = this.parseMethod(isGenerator, isAsync); - } else if (!isPattern && !containsEsc && - this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && - (prop.key.name === "get" || prop.key.name === "set") && - (this.type !== types$1.comma && this.type !== types$1.braceR && this.type !== types$1.eq)) { - if (isGenerator || isAsync) { this.unexpected(); } - prop.kind = prop.key.name; - this.parsePropertyName(prop); - prop.value = this.parseMethod(false); - var paramCount = prop.kind === "get" ? 0 : 1; - if (prop.value.params.length !== paramCount) { - var start = prop.value.start; - if (prop.kind === "get") - { this.raiseRecoverable(start, "getter should have no params"); } - else - { this.raiseRecoverable(start, "setter should have exactly one param"); } - } else { - if (prop.kind === "set" && prop.value.params[0].type === "RestElement") - { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); } - } - } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { - if (isGenerator || isAsync) { this.unexpected(); } - this.checkUnreserved(prop.key); - if (prop.key.name === "await" && !this.awaitIdentPos) - { this.awaitIdentPos = startPos; } - prop.kind = "init"; - if (isPattern) { - prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); - } else if (this.type === types$1.eq && refDestructuringErrors) { - if (refDestructuringErrors.shorthandAssign < 0) - { refDestructuringErrors.shorthandAssign = this.start; } - prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); - } else { - prop.value = this.copyNode(prop.key); - } - prop.shorthand = true; - } else { this.unexpected(); } + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape + pp$1.regexp_eatCharacterEscape = function(state) { + return ( + this.regexp_eatControlEscape(state) || + this.regexp_eatCControlLetter(state) || + this.regexp_eatZero(state) || + this.regexp_eatHexEscapeSequence(state) || + this.regexp_eatRegExpUnicodeEscapeSequence(state, false) || + (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || + this.regexp_eatIdentityEscape(state) + ) }; - - pp$5.parsePropertyName = function(prop) { - if (this.options.ecmaVersion >= 6) { - if (this.eat(types$1.bracketL)) { - prop.computed = true; - prop.key = this.parseMaybeAssign(); - this.expect(types$1.bracketR); - return prop.key - } else { - prop.computed = false; + pp$1.regexp_eatCControlLetter = function(state) { + var start = state.pos; + if (state.eat(0x63 /* c */)) { + if (this.regexp_eatControlLetter(state)) { + return true } + state.pos = start; } - return prop.key = this.type === types$1.num || this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never") + return false }; - - // Initialize empty function node. - - pp$5.initFunction = function(node) { - node.id = null; - if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; } - if (this.options.ecmaVersion >= 8) { node.async = false; } + pp$1.regexp_eatZero = function(state) { + if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) { + state.lastIntValue = 0; + state.advance(); + return true + } + return false }; - // Parse object or class method. - - pp$5.parseMethod = function(isGenerator, isAsync, allowDirectSuper) { - var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; - - this.initFunction(node); - if (this.options.ecmaVersion >= 6) - { node.generator = isGenerator; } - if (this.options.ecmaVersion >= 8) - { node.async = !!isAsync; } - - this.yieldPos = 0; - this.awaitPos = 0; - this.awaitIdentPos = 0; - this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0)); - - this.expect(types$1.parenL); - node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8); - this.checkYieldAwaitInDefaultParams(); - this.parseFunctionBody(node, false, true, false); - - this.yieldPos = oldYieldPos; - this.awaitPos = oldAwaitPos; - this.awaitIdentPos = oldAwaitIdentPos; - return this.finishNode(node, "FunctionExpression") + // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape + pp$1.regexp_eatControlEscape = function(state) { + var ch = state.current(); + if (ch === 0x74 /* t */) { + state.lastIntValue = 0x09; /* \t */ + state.advance(); + return true + } + if (ch === 0x6E /* n */) { + state.lastIntValue = 0x0A; /* \n */ + state.advance(); + return true + } + if (ch === 0x76 /* v */) { + state.lastIntValue = 0x0B; /* \v */ + state.advance(); + return true + } + if (ch === 0x66 /* f */) { + state.lastIntValue = 0x0C; /* \f */ + state.advance(); + return true + } + if (ch === 0x72 /* r */) { + state.lastIntValue = 0x0D; /* \r */ + state.advance(); + return true + } + return false }; - // Parse arrow function expression with given parameters. - - pp$5.parseArrowExpression = function(node, params, isAsync, forInit) { - var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter + pp$1.regexp_eatControlLetter = function(state) { + var ch = state.current(); + if (isControlLetter(ch)) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false + }; + function isControlLetter(ch) { + return ( + (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) || + (ch >= 0x61 /* a */ && ch <= 0x7A /* z */) + ) + } - this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW); - this.initFunction(node); - if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; } + // https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence + pp$1.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) { + if ( forceU === void 0 ) forceU = false; - this.yieldPos = 0; - this.awaitPos = 0; - this.awaitIdentPos = 0; + var start = state.pos; + var switchU = forceU || state.switchU; - node.params = this.toAssignableList(params, true); - this.parseFunctionBody(node, true, false, forInit); + if (state.eat(0x75 /* u */)) { + if (this.regexp_eatFixedHexDigits(state, 4)) { + var lead = state.lastIntValue; + if (switchU && lead >= 0xD800 && lead <= 0xDBFF) { + var leadSurrogateEnd = state.pos; + if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) { + var trail = state.lastIntValue; + if (trail >= 0xDC00 && trail <= 0xDFFF) { + state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000; + return true + } + } + state.pos = leadSurrogateEnd; + state.lastIntValue = lead; + } + return true + } + if ( + switchU && + state.eat(0x7B /* { */) && + this.regexp_eatHexDigits(state) && + state.eat(0x7D /* } */) && + isValidUnicode(state.lastIntValue) + ) { + return true + } + if (switchU) { + state.raise("Invalid unicode escape"); + } + state.pos = start; + } - this.yieldPos = oldYieldPos; - this.awaitPos = oldAwaitPos; - this.awaitIdentPos = oldAwaitIdentPos; - return this.finishNode(node, "ArrowFunctionExpression") + return false }; + function isValidUnicode(ch) { + return ch >= 0 && ch <= 0x10FFFF + } - // Parse function body and check parameters. - - pp$5.parseFunctionBody = function(node, isArrowFunction, isMethod, forInit) { - var isExpression = isArrowFunction && this.type !== types$1.braceL; - var oldStrict = this.strict, useStrict = false; - - if (isExpression) { - node.body = this.parseMaybeAssign(forInit); - node.expression = true; - this.checkParams(node, false); - } else { - var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params); - if (!oldStrict || nonSimple) { - useStrict = this.strictDirective(this.end); - // If this is a strict mode function, verify that argument names - // are not repeated, and it does not try to bind the words `eval` - // or `arguments`. - if (useStrict && nonSimple) - { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape + pp$1.regexp_eatIdentityEscape = function(state) { + if (state.switchU) { + if (this.regexp_eatSyntaxCharacter(state)) { + return true } - // Start a new scope with regard to labels and the `inFunction` - // flag (restore them to their old value afterwards). - var oldLabels = this.labels; - this.labels = []; - if (useStrict) { this.strict = true; } - - // Add the params to varDeclaredNames to ensure that an error is thrown - // if a let/const declaration in the function clashes with one of the params. - this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params)); - // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' - if (this.strict && node.id) { this.checkLValSimple(node.id, BIND_OUTSIDE); } - node.body = this.parseBlock(false, undefined, useStrict && !oldStrict); - node.expression = false; - this.adaptDirectivePrologue(node.body.body); - this.labels = oldLabels; + if (state.eat(0x2F /* / */)) { + state.lastIntValue = 0x2F; /* / */ + return true + } + return false } - this.exitScope(); - }; - pp$5.isSimpleParamList = function(params) { - for (var i = 0, list = params; i < list.length; i += 1) - { - var param = list[i]; + var ch = state.current(); + if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) { + state.lastIntValue = ch; + state.advance(); + return true + } - if (param.type !== "Identifier") { return false - } } - return true + return false }; - // Checks function params for various disallowed patterns such as using "eval" - // or "arguments" and duplicate parameters. - - pp$5.checkParams = function(node, allowDuplicates) { - var nameHash = Object.create(null); - for (var i = 0, list = node.params; i < list.length; i += 1) - { - var param = list[i]; - - this.checkLValInnerPattern(param, BIND_VAR, allowDuplicates ? null : nameHash); + // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape + pp$1.regexp_eatDecimalEscape = function(state) { + state.lastIntValue = 0; + var ch = state.current(); + if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) { + do { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); + } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) + return true } + return false }; - // Parses a comma-separated list of expressions, and returns them as - // an array. `close` is the token type that ends the list, and - // `allowEmpty` can be turned on to allow subsequent commas with - // nothing in between them to be parsed as `null` (which is needed - // for array literals). + // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape + pp$1.regexp_eatCharacterClassEscape = function(state) { + var ch = state.current(); - pp$5.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { - var elts = [], first = true; - while (!this.eat(close)) { - if (!first) { - this.expect(types$1.comma); - if (allowTrailingComma && this.afterTrailingComma(close)) { break } - } else { first = false; } + if (isCharacterClassEscape(ch)) { + state.lastIntValue = -1; + state.advance(); + return true + } - var elt = (void 0); - if (allowEmpty && this.type === types$1.comma) - { elt = null; } - else if (this.type === types$1.ellipsis) { - elt = this.parseSpread(refDestructuringErrors); - if (refDestructuringErrors && this.type === types$1.comma && refDestructuringErrors.trailingComma < 0) - { refDestructuringErrors.trailingComma = this.start; } - } else { - elt = this.parseMaybeAssign(false, refDestructuringErrors); + if ( + state.switchU && + this.options.ecmaVersion >= 9 && + (ch === 0x50 /* P */ || ch === 0x70 /* p */) + ) { + state.lastIntValue = -1; + state.advance(); + if ( + state.eat(0x7B /* { */) && + this.regexp_eatUnicodePropertyValueExpression(state) && + state.eat(0x7D /* } */) + ) { + return true } - elts.push(elt); + state.raise("Invalid property name"); } - return elts - }; - - pp$5.checkUnreserved = function(ref) { - var start = ref.start; - var end = ref.end; - var name = ref.name; - if (this.inGenerator && name === "yield") - { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); } - if (this.inAsync && name === "await") - { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); } - if (this.currentThisScope().inClassFieldInit && name === "arguments") - { this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer"); } - if (this.inClassStaticBlock && (name === "arguments" || name === "await")) - { this.raise(start, ("Cannot use " + name + " in class static initialization block")); } - if (this.keywords.test(name)) - { this.raise(start, ("Unexpected keyword '" + name + "'")); } - if (this.options.ecmaVersion < 6 && - this.input.slice(start, end).indexOf("\\") !== -1) { return } - var re = this.strict ? this.reservedWordsStrict : this.reservedWords; - if (re.test(name)) { - if (!this.inAsync && name === "await") - { this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); } - this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); - } + return false }; + function isCharacterClassEscape(ch) { + return ( + ch === 0x64 /* d */ || + ch === 0x44 /* D */ || + ch === 0x73 /* s */ || + ch === 0x53 /* S */ || + ch === 0x77 /* w */ || + ch === 0x57 /* W */ + ) + } - // Parse the next token as an identifier. If `liberal` is true (used - // when parsing properties), it will also convert keywords into - // identifiers. - - pp$5.parseIdent = function(liberal) { - var node = this.startNode(); - if (this.type === types$1.name) { - node.name = this.value; - } else if (this.type.keyword) { - node.name = this.type.keyword; + // UnicodePropertyValueExpression :: + // UnicodePropertyName `=` UnicodePropertyValue + // LoneUnicodePropertyNameOrValue + pp$1.regexp_eatUnicodePropertyValueExpression = function(state) { + var start = state.pos; - // To fix https://github.com/acornjs/acorn/issues/575 - // `class` and `function` keywords push new context into this.context. - // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. - // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword - if ((node.name === "class" || node.name === "function") && - (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { - this.context.pop(); + // UnicodePropertyName `=` UnicodePropertyValue + if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) { + var name = state.lastStringValue; + if (this.regexp_eatUnicodePropertyValue(state)) { + var value = state.lastStringValue; + this.regexp_validateUnicodePropertyNameAndValue(state, name, value); + return true } - } else { - this.unexpected(); } - this.next(!!liberal); - this.finishNode(node, "Identifier"); - if (!liberal) { - this.checkUnreserved(node); - if (node.name === "await" && !this.awaitIdentPos) - { this.awaitIdentPos = node.start; } + state.pos = start; + + // LoneUnicodePropertyNameOrValue + if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { + var nameOrValue = state.lastStringValue; + this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue); + return true } - return node + return false + }; + pp$1.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) { + if (!hasOwn(state.unicodeProperties.nonBinary, name)) + { state.raise("Invalid property name"); } + if (!state.unicodeProperties.nonBinary[name].test(value)) + { state.raise("Invalid property value"); } + }; + pp$1.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) { + if (!state.unicodeProperties.binary.test(nameOrValue)) + { state.raise("Invalid property name"); } }; - pp$5.parsePrivateIdent = function() { - var node = this.startNode(); - if (this.type === types$1.privateId) { - node.name = this.value; - } else { - this.unexpected(); + // UnicodePropertyName :: + // UnicodePropertyNameCharacters + pp$1.regexp_eatUnicodePropertyName = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyNameCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); } - this.next(); - this.finishNode(node, "PrivateIdentifier"); + return state.lastStringValue !== "" + }; + function isUnicodePropertyNameCharacter(ch) { + return isControlLetter(ch) || ch === 0x5F /* _ */ + } - // For validating existence - if (this.privateNameStack.length === 0) { - this.raise(node.start, ("Private field '#" + (node.name) + "' must be declared in an enclosing class")); - } else { - this.privateNameStack[this.privateNameStack.length - 1].used.push(node); + // UnicodePropertyValue :: + // UnicodePropertyValueCharacters + pp$1.regexp_eatUnicodePropertyValue = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyValueCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); } - - return node + return state.lastStringValue !== "" }; + function isUnicodePropertyValueCharacter(ch) { + return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch) + } - // Parses yield expression inside generator. - - pp$5.parseYield = function(forInit) { - if (!this.yieldPos) { this.yieldPos = this.start; } + // LoneUnicodePropertyNameOrValue :: + // UnicodePropertyValueCharacters + pp$1.regexp_eatLoneUnicodePropertyNameOrValue = function(state) { + return this.regexp_eatUnicodePropertyValue(state) + }; - var node = this.startNode(); - this.next(); - if (this.type === types$1.semi || this.canInsertSemicolon() || (this.type !== types$1.star && !this.type.startsExpr)) { - node.delegate = false; - node.argument = null; - } else { - node.delegate = this.eat(types$1.star); - node.argument = this.parseMaybeAssign(forInit); + // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass + pp$1.regexp_eatCharacterClass = function(state) { + if (state.eat(0x5B /* [ */)) { + state.eat(0x5E /* ^ */); + this.regexp_classRanges(state); + if (state.eat(0x5D /* ] */)) { + return true + } + // Unreachable since it threw "unterminated regular expression" error before. + state.raise("Unterminated character class"); } - return this.finishNode(node, "YieldExpression") + return false }; - pp$5.parseAwait = function(forInit) { - if (!this.awaitPos) { this.awaitPos = this.start; } - - var node = this.startNode(); - this.next(); - node.argument = this.parseMaybeUnary(null, true, false, forInit); - return this.finishNode(node, "AwaitExpression") + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges + // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges + // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash + pp$1.regexp_classRanges = function(state) { + while (this.regexp_eatClassAtom(state)) { + var left = state.lastIntValue; + if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) { + var right = state.lastIntValue; + if (state.switchU && (left === -1 || right === -1)) { + state.raise("Invalid character class"); + } + if (left !== -1 && right !== -1 && left > right) { + state.raise("Range out of order in character class"); + } + } + } }; - var pp$4 = Parser.prototype; + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash + pp$1.regexp_eatClassAtom = function(state) { + var start = state.pos; - // This function is used to raise exceptions on parse errors. It - // takes an offset integer (into the current `input`) to indicate - // the location of the error, attaches the position to the end - // of the error message, and then raises a `SyntaxError` with that - // message. + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatClassEscape(state)) { + return true + } + if (state.switchU) { + // Make the same message as V8. + var ch$1 = state.current(); + if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) { + state.raise("Invalid class escape"); + } + state.raise("Invalid escape"); + } + state.pos = start; + } - pp$4.raise = function(pos, message) { - var loc = getLineInfo(this.input, pos); - message += " (" + loc.line + ":" + loc.column + ")"; - var err = new SyntaxError(message); - err.pos = pos; err.loc = loc; err.raisedAt = this.pos; - throw err + var ch = state.current(); + if (ch !== 0x5D /* ] */) { + state.lastIntValue = ch; + state.advance(); + return true + } + + return false }; - pp$4.raiseRecoverable = pp$4.raise; + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape + pp$1.regexp_eatClassEscape = function(state) { + var start = state.pos; - pp$4.curPosition = function() { - if (this.options.locations) { - return new Position(this.curLine, this.pos - this.lineStart) + if (state.eat(0x62 /* b */)) { + state.lastIntValue = 0x08; /* */ + return true } - }; - var pp$3 = Parser.prototype; - - var Scope = function Scope(flags) { - this.flags = flags; - // A list of var-declared names in the current lexical scope - this.var = []; - // A list of lexically-declared names in the current lexical scope - this.lexical = []; - // A list of lexically-declared FunctionDeclaration names in the current lexical scope - this.functions = []; - // A switch to disallow the identifier reference 'arguments' - this.inClassFieldInit = false; - }; + if (state.switchU && state.eat(0x2D /* - */)) { + state.lastIntValue = 0x2D; /* - */ + return true + } - // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. + if (!state.switchU && state.eat(0x63 /* c */)) { + if (this.regexp_eatClassControlLetter(state)) { + return true + } + state.pos = start; + } - pp$3.enterScope = function(flags) { - this.scopeStack.push(new Scope(flags)); + return ( + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) + ) }; - pp$3.exitScope = function() { - this.scopeStack.pop(); - }; - - // The spec says: - // > At the top level of a function, or script, function declarations are - // > treated like var declarations rather than like lexical declarations. - pp$3.treatFunctionsAsVarInScope = function(scope) { - return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP) + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter + pp$1.regexp_eatClassControlLetter = function(state) { + var ch = state.current(); + if (isDecimalDigit(ch) || ch === 0x5F /* _ */) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false }; - pp$3.declareName = function(name, bindingType, pos) { - var redeclared = false; - if (bindingType === BIND_LEXICAL) { - var scope = this.currentScope(); - redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1; - scope.lexical.push(name); - if (this.inModule && (scope.flags & SCOPE_TOP)) - { delete this.undefinedExports[name]; } - } else if (bindingType === BIND_SIMPLE_CATCH) { - var scope$1 = this.currentScope(); - scope$1.lexical.push(name); - } else if (bindingType === BIND_FUNCTION) { - var scope$2 = this.currentScope(); - if (this.treatFunctionsAsVar) - { redeclared = scope$2.lexical.indexOf(name) > -1; } - else - { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; } - scope$2.functions.push(name); - } else { - for (var i = this.scopeStack.length - 1; i >= 0; --i) { - var scope$3 = this.scopeStack[i]; - if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) || - !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) { - redeclared = true; - break - } - scope$3.var.push(name); - if (this.inModule && (scope$3.flags & SCOPE_TOP)) - { delete this.undefinedExports[name]; } - if (scope$3.flags & SCOPE_VAR) { break } + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence + pp$1.regexp_eatHexEscapeSequence = function(state) { + var start = state.pos; + if (state.eat(0x78 /* x */)) { + if (this.regexp_eatFixedHexDigits(state, 2)) { + return true } + if (state.switchU) { + state.raise("Invalid escape"); + } + state.pos = start; } - if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); } + return false }; - pp$3.checkLocalExport = function(id) { - // scope.functions must be empty as Module code is always strict. - if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && - this.scopeStack[0].var.indexOf(id.name) === -1) { - this.undefinedExports[id.name] = id; + // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits + pp$1.regexp_eatDecimalDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isDecimalDigit(ch = state.current())) { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); } + return state.pos !== start }; + function isDecimalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */ + } - pp$3.currentScope = function() { - return this.scopeStack[this.scopeStack.length - 1] + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits + pp$1.regexp_eatHexDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isHexDigit(ch = state.current())) { + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); + } + return state.pos !== start }; + function isHexDigit(ch) { + return ( + (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) || + (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) || + (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) + ) + } + function hexToInt(ch) { + if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) { + return 10 + (ch - 0x41 /* A */) + } + if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) { + return 10 + (ch - 0x61 /* a */) + } + return ch - 0x30 /* 0 */ + } - pp$3.currentVarScope = function() { - for (var i = this.scopeStack.length - 1;; i--) { - var scope = this.scopeStack[i]; - if (scope.flags & SCOPE_VAR) { return scope } + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence + // Allows only 0-377(octal) i.e. 0-255(decimal). + pp$1.regexp_eatLegacyOctalEscapeSequence = function(state) { + if (this.regexp_eatOctalDigit(state)) { + var n1 = state.lastIntValue; + if (this.regexp_eatOctalDigit(state)) { + var n2 = state.lastIntValue; + if (n1 <= 3 && this.regexp_eatOctalDigit(state)) { + state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue; + } else { + state.lastIntValue = n1 * 8 + n2; + } + } else { + state.lastIntValue = n1; + } + return true } + return false }; - // Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`. - pp$3.currentThisScope = function() { - for (var i = this.scopeStack.length - 1;; i--) { - var scope = this.scopeStack[i]; - if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope } + // https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit + pp$1.regexp_eatOctalDigit = function(state) { + var ch = state.current(); + if (isOctalDigit(ch)) { + state.lastIntValue = ch - 0x30; /* 0 */ + state.advance(); + return true } + state.lastIntValue = 0; + return false }; + function isOctalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */ + } - var Node = function Node(parser, pos, loc) { - this.type = ""; - this.start = pos; - this.end = 0; - if (parser.options.locations) - { this.loc = new SourceLocation(parser, loc); } - if (parser.options.directSourceFile) - { this.sourceFile = parser.options.directSourceFile; } - if (parser.options.ranges) - { this.range = [pos, 0]; } + // https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit + // And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence + pp$1.regexp_eatFixedHexDigits = function(state, length) { + var start = state.pos; + state.lastIntValue = 0; + for (var i = 0; i < length; ++i) { + var ch = state.current(); + if (!isHexDigit(ch)) { + state.pos = start; + return false + } + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); + } + return true }; - // Start an AST node, attaching a start offset. - - var pp$2 = Parser.prototype; - - pp$2.startNode = function() { - return new Node(this, this.start, this.startLoc) - }; + // Object type used to represent tokens. Note that normally, tokens + // simply exist as properties on the parser object. This is only + // used for the onToken callback and the external tokenizer. - pp$2.startNodeAt = function(pos, loc) { - return new Node(this, pos, loc) + var Token = function Token(p) { + this.type = p.type; + this.value = p.value; + this.start = p.start; + this.end = p.end; + if (p.options.locations) + { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); } + if (p.options.ranges) + { this.range = [p.start, p.end]; } }; - // Finish an AST node, adding `type` and `end` properties. - - function finishNodeAt(node, type, pos, loc) { - node.type = type; - node.end = pos; - if (this.options.locations) - { node.loc.end = loc; } - if (this.options.ranges) - { node.range[1] = pos; } - return node - } + // ## Tokenizer - pp$2.finishNode = function(node, type) { - return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) - }; + var pp = Parser.prototype; - // Finish node at given position + // Move to the next token - pp$2.finishNodeAt = function(node, type, pos, loc) { - return finishNodeAt.call(this, node, type, pos, loc) - }; + pp.next = function(ignoreEscapeSequenceInKeyword) { + if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc) + { this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); } + if (this.options.onToken) + { this.options.onToken(new Token(this)); } - pp$2.copyNode = function(node) { - var newNode = new Node(this, node.start, this.startLoc); - for (var prop in node) { newNode[prop] = node[prop]; } - return newNode + this.lastTokEnd = this.end; + this.lastTokStart = this.start; + this.lastTokEndLoc = this.endLoc; + this.lastTokStartLoc = this.startLoc; + this.nextToken(); }; - // This file contains Unicode properties extracted from the ECMAScript specification. - // The lists are extracted like so: - // $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText) - - // #table-binary-unicode-properties - var ecma9BinaryProperties = "ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS"; - var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic"; - var ecma11BinaryProperties = ecma10BinaryProperties; - var ecma12BinaryProperties = ecma11BinaryProperties + " EBase EComp EMod EPres ExtPict"; - var ecma13BinaryProperties = ecma12BinaryProperties; - var ecma14BinaryProperties = ecma13BinaryProperties; - - var unicodeBinaryProperties = { - 9: ecma9BinaryProperties, - 10: ecma10BinaryProperties, - 11: ecma11BinaryProperties, - 12: ecma12BinaryProperties, - 13: ecma13BinaryProperties, - 14: ecma14BinaryProperties + pp.getToken = function() { + this.next(); + return new Token(this) }; - // #table-unicode-general-category-values - var unicodeGeneralCategoryValues = "Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu"; - - // #table-unicode-script-values - var ecma9ScriptValues = "Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb"; - var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd"; - var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"; - var ecma12ScriptValues = ecma11ScriptValues + " Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi"; - var ecma13ScriptValues = ecma12ScriptValues + " Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith"; - var ecma14ScriptValues = ecma13ScriptValues + " Kawi Nag_Mundari Nagm"; - - var unicodeScriptValues = { - 9: ecma9ScriptValues, - 10: ecma10ScriptValues, - 11: ecma11ScriptValues, - 12: ecma12ScriptValues, - 13: ecma13ScriptValues, - 14: ecma14ScriptValues - }; + // If we're in an ES6 environment, make parsers iterable + if (typeof Symbol !== "undefined") + { pp[Symbol.iterator] = function() { + var this$1$1 = this; - var data = {}; - function buildUnicodeData(ecmaVersion) { - var d = data[ecmaVersion] = { - binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues), - nonBinary: { - General_Category: wordsRegexp(unicodeGeneralCategoryValues), - Script: wordsRegexp(unicodeScriptValues[ecmaVersion]) + return { + next: function () { + var token = this$1$1.getToken(); + return { + done: token.type === types$1.eof, + value: token + } + } } - }; - d.nonBinary.Script_Extensions = d.nonBinary.Script; + }; } - d.nonBinary.gc = d.nonBinary.General_Category; - d.nonBinary.sc = d.nonBinary.Script; - d.nonBinary.scx = d.nonBinary.Script_Extensions; - } + // Toggle strict mode. Re-reads the next number or string to please + // pedantic tests (`"use strict"; 010;` should fail). - for (var i = 0, list = [9, 10, 11, 12, 13, 14]; i < list.length; i += 1) { - var ecmaVersion = list[i]; + // Read a single token, updating the parser object's token-related + // properties. - buildUnicodeData(ecmaVersion); - } + pp.nextToken = function() { + var curContext = this.curContext(); + if (!curContext || !curContext.preserveSpace) { this.skipSpace(); } - var pp$1 = Parser.prototype; + this.start = this.pos; + if (this.options.locations) { this.startLoc = this.curPosition(); } + if (this.pos >= this.input.length) { return this.finishToken(types$1.eof) } - var RegExpValidationState = function RegExpValidationState(parser) { - this.parser = parser; - this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : ""); - this.unicodeProperties = data[parser.options.ecmaVersion >= 14 ? 14 : parser.options.ecmaVersion]; - this.source = ""; - this.flags = ""; - this.start = 0; - this.switchU = false; - this.switchN = false; - this.pos = 0; - this.lastIntValue = 0; - this.lastStringValue = ""; - this.lastAssertionIsQuantifiable = false; - this.numCapturingParens = 0; - this.maxBackReference = 0; - this.groupNames = []; - this.backReferenceNames = []; + if (curContext.override) { return curContext.override(this) } + else { this.readToken(this.fullCharCodeAtPos()); } }; - RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { - var unicode = flags.indexOf("u") !== -1; - this.start = start | 0; - this.source = pattern + ""; - this.flags = flags; - this.switchU = unicode && this.parser.options.ecmaVersion >= 6; - this.switchN = unicode && this.parser.options.ecmaVersion >= 9; - }; + pp.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + { return this.readWord() } - RegExpValidationState.prototype.raise = function raise (message) { - this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message)); + return this.getTokenFromCode(code) }; - // If u flag is given, this returns the code point at the index (it combines a surrogate pair). - // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair). - RegExpValidationState.prototype.at = function at (i, forceU) { - if ( forceU === void 0 ) forceU = false; + pp.fullCharCodeAtPos = function() { + var code = this.input.charCodeAt(this.pos); + if (code <= 0xd7ff || code >= 0xdc00) { return code } + var next = this.input.charCodeAt(this.pos + 1); + return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00 + }; - var s = this.source; - var l = s.length; - if (i >= l) { - return -1 + pp.skipBlockComment = function() { + var startLoc = this.options.onComment && this.curPosition(); + var start = this.pos, end = this.input.indexOf("*/", this.pos += 2); + if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); } + this.pos = end + 2; + if (this.options.locations) { + for (var nextBreak = (void 0), pos = start; (nextBreak = nextLineBreak(this.input, pos, this.pos)) > -1;) { + ++this.curLine; + pos = this.lineStart = nextBreak; + } } - var c = s.charCodeAt(i); - if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { - return c + if (this.options.onComment) + { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()); } + }; + + pp.skipLineComment = function(startSkip) { + var start = this.pos; + var startLoc = this.options.onComment && this.curPosition(); + var ch = this.input.charCodeAt(this.pos += startSkip); + while (this.pos < this.input.length && !isNewLine(ch)) { + ch = this.input.charCodeAt(++this.pos); } - var next = s.charCodeAt(i + 1); - return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c + if (this.options.onComment) + { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()); } }; - RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) { - if ( forceU === void 0 ) forceU = false; + // Called at the start of the parse and after every token. Skips + // whitespace and comments, and. - var s = this.source; - var l = s.length; - if (i >= l) { - return l - } - var c = s.charCodeAt(i), next; - if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l || - (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) { - return i + 1 + pp.skipSpace = function() { + loop: while (this.pos < this.input.length) { + var ch = this.input.charCodeAt(this.pos); + switch (ch) { + case 32: case 160: // ' ' + ++this.pos; + break + case 13: + if (this.input.charCodeAt(this.pos + 1) === 10) { + ++this.pos; + } + case 10: case 8232: case 8233: + ++this.pos; + if (this.options.locations) { + ++this.curLine; + this.lineStart = this.pos; + } + break + case 47: // '/' + switch (this.input.charCodeAt(this.pos + 1)) { + case 42: // '*' + this.skipBlockComment(); + break + case 47: + this.skipLineComment(2); + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this.pos; + } else { + break loop + } + } } - return i + 2 }; - RegExpValidationState.prototype.current = function current (forceU) { - if ( forceU === void 0 ) forceU = false; + // Called at the end of every token. Sets `end`, `val`, and + // maintains `context` and `exprAllowed`, and skips the space after + // the token, so that the next one's `start` will point at the + // right position. - return this.at(this.pos, forceU) + pp.finishToken = function(type, val) { + this.end = this.pos; + if (this.options.locations) { this.endLoc = this.curPosition(); } + var prevType = this.type; + this.type = type; + this.value = val; + + this.updateContext(prevType); }; - RegExpValidationState.prototype.lookahead = function lookahead (forceU) { - if ( forceU === void 0 ) forceU = false; + // ### Token reading - return this.at(this.nextIndex(this.pos, forceU), forceU) + // This is the function that is called to fetch the next token. It + // is somewhat obscure, because it works in character codes rather + // than characters, and because operator parsing has been inlined + // into it. + // + // All in the name of speed. + // + pp.readToken_dot = function() { + var next = this.input.charCodeAt(this.pos + 1); + if (next >= 48 && next <= 57) { return this.readNumber(true) } + var next2 = this.input.charCodeAt(this.pos + 2); + if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' + this.pos += 3; + return this.finishToken(types$1.ellipsis) + } else { + ++this.pos; + return this.finishToken(types$1.dot) + } }; - RegExpValidationState.prototype.advance = function advance (forceU) { - if ( forceU === void 0 ) forceU = false; - - this.pos = this.nextIndex(this.pos, forceU); + pp.readToken_slash = function() { // '/' + var next = this.input.charCodeAt(this.pos + 1); + if (this.exprAllowed) { ++this.pos; return this.readRegexp() } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.slash, 1) }; - RegExpValidationState.prototype.eat = function eat (ch, forceU) { - if ( forceU === void 0 ) forceU = false; + pp.readToken_mult_modulo_exp = function(code) { // '%*' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + var tokentype = code === 42 ? types$1.star : types$1.modulo; - if (this.current(forceU) === ch) { - this.advance(forceU); - return true + // exponentiation operator ** and **= + if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) { + ++size; + tokentype = types$1.starstar; + next = this.input.charCodeAt(this.pos + 2); } - return false - }; - /** - * Validate the flags part of a given RegExpLiteral. - * - * @param {RegExpValidationState} state The state to validate RegExp. - * @returns {void} - */ - pp$1.validateRegExpFlags = function(state) { - var validFlags = state.validFlags; - var flags = state.flags; + if (next === 61) { return this.finishOp(types$1.assign, size + 1) } + return this.finishOp(tokentype, size) + }; - for (var i = 0; i < flags.length; i++) { - var flag = flags.charAt(i); - if (validFlags.indexOf(flag) === -1) { - this.raise(state.start, "Invalid regular expression flag"); - } - if (flags.indexOf(flag, i + 1) > -1) { - this.raise(state.start, "Duplicate regular expression flag"); + pp.readToken_pipe_amp = function(code) { // '|&' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (this.options.ecmaVersion >= 12) { + var next2 = this.input.charCodeAt(this.pos + 2); + if (next2 === 61) { return this.finishOp(types$1.assign, 3) } } + return this.finishOp(code === 124 ? types$1.logicalOR : types$1.logicalAND, 2) } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(code === 124 ? types$1.bitwiseOR : types$1.bitwiseAND, 1) }; - /** - * Validate the pattern part of a given RegExpLiteral. - * - * @param {RegExpValidationState} state The state to validate RegExp. - * @returns {void} - */ - pp$1.validateRegExpPattern = function(state) { - this.regexp_pattern(state); + pp.readToken_caret = function() { // '^' + var next = this.input.charCodeAt(this.pos + 1); + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.bitwiseXOR, 1) + }; - // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of - // parsing contains a |GroupName|, reparse with the goal symbol - // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* - // exception if _P_ did not conform to the grammar, if any elements of _P_ - // were not matched by the parse, or if any Early Error conditions exist. - if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { - state.switchN = true; - this.regexp_pattern(state); + pp.readToken_plus_min = function(code) { // '+-' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 && + (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) { + // A `-->` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types$1.incDec, 2) } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.plusMin, 1) }; - // https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern - pp$1.regexp_pattern = function(state) { - state.pos = 0; - state.lastIntValue = 0; - state.lastStringValue = ""; - state.lastAssertionIsQuantifiable = false; - state.numCapturingParens = 0; - state.maxBackReference = 0; - state.groupNames.length = 0; - state.backReferenceNames.length = 0; + pp.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; + if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) } + return this.finishOp(types$1.bitShift, size) + } + if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && + this.input.charCodeAt(this.pos + 3) === 45) { + // `` line comment - this.skipLineComment(3); - this.skipSpace(); - return this.nextToken() - } - return this.finishOp(types$1.incDec, 2) - } - if (next === 61) { return this.finishOp(types$1.assign, 2) } - return this.finishOp(types$1.plusMin, 1) - }; +var iterate = __nccwpck_require__(9023) + , initState = __nccwpck_require__(2474) + , terminator = __nccwpck_require__(7942) + ; - pp.readToken_lt_gt = function(code) { // '<>' - var next = this.input.charCodeAt(this.pos + 1); - var size = 1; - if (next === code) { - size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; - if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) } - return this.finishOp(types$1.bitShift, size) - } - if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && - this.input.charCodeAt(this.pos + 3) === 45) { - // `` line comment\n this.skipLineComment(3);\n this.skipSpace();\n return this.nextToken()\n }\n return this.finishOp(types$1.incDec, 2)\n }\n if (next === 61) { return this.finishOp(types$1.assign, 2) }\n return this.finishOp(types$1.plusMin, 1)\n };\n\n pp.readToken_lt_gt = function(code) { // '<>'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n if (next === code) {\n size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;\n if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) }\n return this.finishOp(types$1.bitShift, size)\n }\n if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&\n this.input.charCodeAt(this.pos + 3) === 45) {\n // `\\n\\n'\n }\n }\n\n return '\\n\\n'\n}\n","/**\n * @typedef {import('../types.js').IndentLines} IndentLines\n */\n\nconst eol = /\\r?\\n|\\r/g\n\n/**\n * @type {IndentLines}\n */\nexport function indentLines(value, map) {\n /** @type {Array} */\n const result = []\n let start = 0\n let line = 0\n /** @type {RegExpExecArray | null} */\n let match\n\n while ((match = eol.exec(value))) {\n one(value.slice(start, match.index))\n result.push(match[0])\n start = match.index + match[0].length\n line++\n }\n\n one(value.slice(start))\n\n return result.join('')\n\n /**\n * @param {string} value\n */\n function one(value) {\n result.push(map(value, line, !value))\n }\n}\n","/**\n * @typedef {import('../types.js').State} State\n * @typedef {import('../types.js').SafeConfig} SafeConfig\n */\n\nimport {patternCompile} from './pattern-compile.js'\nimport {patternInScope} from './pattern-in-scope.js'\n\n/**\n * Make a string safe for embedding in markdown constructs.\n *\n * In markdown, almost all punctuation characters can, in certain cases,\n * result in something.\n * Whether they do is highly subjective to where they happen and in what\n * they happen.\n *\n * To solve this, `mdast-util-to-markdown` tracks:\n *\n * * Characters before and after something;\n * * What “constructs” we are in.\n *\n * This information is then used by this function to escape or encode\n * special characters.\n *\n * @param {State} state\n * Info passed around about the current state.\n * @param {string | null | undefined} input\n * Raw value to make safe.\n * @param {SafeConfig} config\n * Configuration.\n * @returns {string}\n * Serialized markdown safe for embedding.\n */\nexport function safe(state, input, config) {\n const value = (config.before || '') + (input || '') + (config.after || '')\n /** @type {Array} */\n const positions = []\n /** @type {Array} */\n const result = []\n /** @type {Record} */\n const infos = {}\n let index = -1\n\n while (++index < state.unsafe.length) {\n const pattern = state.unsafe[index]\n\n if (!patternInScope(state.stack, pattern)) {\n continue\n }\n\n const expression = patternCompile(pattern)\n /** @type {RegExpExecArray | null} */\n let match\n\n while ((match = expression.exec(value))) {\n const before = 'before' in pattern || Boolean(pattern.atBreak)\n const after = 'after' in pattern\n const position = match.index + (before ? match[1].length : 0)\n\n if (positions.includes(position)) {\n if (infos[position].before && !before) {\n infos[position].before = false\n }\n\n if (infos[position].after && !after) {\n infos[position].after = false\n }\n } else {\n positions.push(position)\n infos[position] = {before, after}\n }\n }\n }\n\n positions.sort(numerical)\n\n let start = config.before ? config.before.length : 0\n const end = value.length - (config.after ? config.after.length : 0)\n index = -1\n\n while (++index < positions.length) {\n const position = positions[index]\n\n // Character before or after matched:\n if (position < start || position >= end) {\n continue\n }\n\n // If this character is supposed to be escaped because it has a condition on\n // the next character, and the next character is definitly being escaped,\n // then skip this escape.\n if (\n (position + 1 < end &&\n positions[index + 1] === position + 1 &&\n infos[position].after &&\n !infos[position + 1].before &&\n !infos[position + 1].after) ||\n (positions[index - 1] === position - 1 &&\n infos[position].before &&\n !infos[position - 1].before &&\n !infos[position - 1].after)\n ) {\n continue\n }\n\n if (start !== position) {\n // If we have to use a character reference, an ampersand would be more\n // correct, but as backslashes only care about punctuation, either will\n // do the trick\n result.push(escapeBackslashes(value.slice(start, position), '\\\\'))\n }\n\n start = position\n\n if (\n /[!-/:-@[-`{-~]/.test(value.charAt(position)) &&\n (!config.encode || !config.encode.includes(value.charAt(position)))\n ) {\n // Character escape.\n result.push('\\\\')\n } else {\n // Character reference.\n result.push(\n '&#x' + value.charCodeAt(position).toString(16).toUpperCase() + ';'\n )\n start++\n }\n }\n\n result.push(escapeBackslashes(value.slice(start, end), config.after))\n\n return result.join('')\n}\n\n/**\n * @param {number} a\n * @param {number} b\n * @returns {number}\n */\nfunction numerical(a, b) {\n return a - b\n}\n\n/**\n * @param {string} value\n * @param {string} after\n * @returns {string}\n */\nfunction escapeBackslashes(value, after) {\n const expression = /\\\\(?=[!-/:-@[-`{-~])/g\n /** @type {Array} */\n const positions = []\n /** @type {Array} */\n const results = []\n const whole = value + after\n let index = -1\n let start = 0\n /** @type {RegExpExecArray | null} */\n let match\n\n while ((match = expression.exec(whole))) {\n positions.push(match.index)\n }\n\n while (++index < positions.length) {\n if (start !== positions[index]) {\n results.push(value.slice(start, positions[index]))\n }\n\n results.push('\\\\')\n start = positions[index]\n }\n\n results.push(value.slice(start))\n\n return results.join('')\n}\n","/**\n * @typedef {import('../types.js').CreateTracker} CreateTracker\n * @typedef {import('../types.js').TrackCurrent} TrackCurrent\n * @typedef {import('../types.js').TrackMove} TrackMove\n * @typedef {import('../types.js').TrackShift} TrackShift\n */\n\n/**\n * Track positional info in the output.\n *\n * @type {CreateTracker}\n */\nexport function track(config) {\n // Defaults are used to prevent crashes when older utilities somehow activate\n // this code.\n /* c8 ignore next 5 */\n const options = config || {}\n const now = options.now || {}\n let lineShift = options.lineShift || 0\n let line = now.line || 1\n let column = now.column || 1\n\n return {move, current, shift}\n\n /**\n * Get the current tracked info.\n *\n * @type {TrackCurrent}\n */\n function current() {\n return {now: {line, column}, lineShift}\n }\n\n /**\n * Define an increased line shift (the typical indent for lines).\n *\n * @type {TrackShift}\n */\n function shift(value) {\n lineShift += value\n }\n\n /**\n * Move past some generated markdown.\n *\n * @type {TrackMove}\n */\n function move(input) {\n // eslint-disable-next-line unicorn/prefer-default-parameters\n const value = input || ''\n const chunks = value.split(/\\r?\\n|\\r/g)\n const tail = chunks[chunks.length - 1]\n line += chunks.length - 1\n column =\n chunks.length === 1 ? column + tail.length : 1 + tail.length + lineShift\n return value\n }\n}\n","/**\n * @typedef {import('./types.js').Enter} Enter\n * @typedef {import('./types.js').Info} Info\n * @typedef {import('./types.js').Join} Join\n * @typedef {import('./types.js').FlowContent} FlowContent\n * @typedef {import('./types.js').Node} Node\n * @typedef {import('./types.js').Options} Options\n * @typedef {import('./types.js').Parent} Parent\n * @typedef {import('./types.js').PhrasingContent} PhrasingContent\n * @typedef {import('./types.js').SafeConfig} SafeConfig\n * @typedef {import('./types.js').State} State\n * @typedef {import('./types.js').TrackFields} TrackFields\n */\n\nimport {zwitch} from 'zwitch'\nimport {configure} from './configure.js'\nimport {handle as handlers} from './handle/index.js'\nimport {join} from './join.js'\nimport {unsafe} from './unsafe.js'\nimport {association} from './util/association.js'\nimport {containerPhrasing} from './util/container-phrasing.js'\nimport {containerFlow} from './util/container-flow.js'\nimport {indentLines} from './util/indent-lines.js'\nimport {safe} from './util/safe.js'\nimport {track} from './util/track.js'\n\n/**\n * Turn an mdast syntax tree into markdown.\n *\n * @param {Node} tree\n * Tree to serialize.\n * @param {Options} [options]\n * Configuration (optional).\n * @returns {string}\n * Serialized markdown representing `tree`.\n */\nexport function toMarkdown(tree, options = {}) {\n /** @type {State} */\n const state = {\n enter,\n indentLines,\n associationId: association,\n containerPhrasing: containerPhrasingBound,\n containerFlow: containerFlowBound,\n createTracker: track,\n safe: safeBound,\n stack: [],\n unsafe: [],\n join: [],\n // @ts-expect-error: we’ll fill it next.\n handlers: {},\n options: {},\n indexStack: [],\n // @ts-expect-error: we’ll add `handle` later.\n handle: undefined\n }\n\n configure(state, {unsafe, join, handlers})\n configure(state, options)\n\n if (state.options.tightDefinitions) {\n configure(state, {join: [joinDefinition]})\n }\n\n state.handle = zwitch('type', {\n invalid,\n unknown,\n handlers: state.handlers\n })\n\n let result = state.handle(tree, undefined, state, {\n before: '\\n',\n after: '\\n',\n now: {line: 1, column: 1},\n lineShift: 0\n })\n\n if (\n result &&\n result.charCodeAt(result.length - 1) !== 10 &&\n result.charCodeAt(result.length - 1) !== 13\n ) {\n result += '\\n'\n }\n\n return result\n\n /** @type {Enter} */\n function enter(name) {\n state.stack.push(name)\n return exit\n\n function exit() {\n state.stack.pop()\n }\n }\n}\n\n/**\n * @param {unknown} value\n * @returns {never}\n */\nfunction invalid(value) {\n throw new Error('Cannot handle value `' + value + '`, expected node')\n}\n\n/**\n * @param {unknown} node\n * @returns {never}\n */\nfunction unknown(node) {\n // @ts-expect-error: fine.\n throw new Error('Cannot handle unknown node `' + node.type + '`')\n}\n\n/** @type {Join} */\nfunction joinDefinition(left, right) {\n // No blank line between adjacent definitions.\n if (left.type === 'definition' && left.type === right.type) {\n return 0\n }\n}\n\n/**\n * Serialize the children of a parent that contains phrasing children.\n *\n * These children will be joined flush together.\n *\n * @this {State}\n * Info passed around about the current state.\n * @param {Parent & {children: Array}} parent\n * Parent of flow nodes.\n * @param {Info} info\n * Info on where we are in the document we are generating.\n * @returns {string}\n * Serialized children, joined together.\n */\nfunction containerPhrasingBound(parent, info) {\n return containerPhrasing(parent, this, info)\n}\n\n/**\n * Serialize the children of a parent that contains flow children.\n *\n * These children will typically be joined by blank lines.\n * What they are joined by exactly is defined by `Join` functions.\n *\n * @this {State}\n * Info passed around about the current state.\n * @param {Parent & {children: Array}} parent\n * Parent of flow nodes.\n * @param {TrackFields} info\n * Info on where we are in the document we are generating.\n * @returns {string}\n * Serialized children, joined by (blank) lines.\n */\nfunction containerFlowBound(parent, info) {\n return containerFlow(parent, this, info)\n}\n\n/**\n * Make a string safe for embedding in markdown constructs.\n *\n * In markdown, almost all punctuation characters can, in certain cases,\n * result in something.\n * Whether they do is highly subjective to where they happen and in what\n * they happen.\n *\n * To solve this, `mdast-util-to-markdown` tracks:\n *\n * * Characters before and after something;\n * * What “constructs” we are in.\n *\n * This information is then used by this function to escape or encode\n * special characters.\n *\n * @this {State}\n * Info passed around about the current state.\n * @param {string | null | undefined} value\n * Raw value to make safe.\n * @param {SafeConfig} config\n * Configuration.\n * @returns {string}\n * Serialized markdown safe for embedding.\n */\nfunction safeBound(value, config) {\n return safe(this, value, config)\n}\n","// This file was generated. Do not modify manually!\nvar astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 81, 2, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 9, 5351, 0, 7, 14, 13835, 9, 87, 9, 39, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4706, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 983, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];\n\n// This file was generated. Do not modify manually!\nvar astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 68, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 4026, 582, 8634, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8936, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 757, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4153, 7, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938, 6, 4191];\n\n// This file was generated. Do not modify manually!\nvar nonASCIIidentifierChars = \"\\u200c\\u200d\\xb7\\u0300-\\u036f\\u0387\\u0483-\\u0487\\u0591-\\u05bd\\u05bf\\u05c1\\u05c2\\u05c4\\u05c5\\u05c7\\u0610-\\u061a\\u064b-\\u0669\\u0670\\u06d6-\\u06dc\\u06df-\\u06e4\\u06e7\\u06e8\\u06ea-\\u06ed\\u06f0-\\u06f9\\u0711\\u0730-\\u074a\\u07a6-\\u07b0\\u07c0-\\u07c9\\u07eb-\\u07f3\\u07fd\\u0816-\\u0819\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0859-\\u085b\\u0898-\\u089f\\u08ca-\\u08e1\\u08e3-\\u0903\\u093a-\\u093c\\u093e-\\u094f\\u0951-\\u0957\\u0962\\u0963\\u0966-\\u096f\\u0981-\\u0983\\u09bc\\u09be-\\u09c4\\u09c7\\u09c8\\u09cb-\\u09cd\\u09d7\\u09e2\\u09e3\\u09e6-\\u09ef\\u09fe\\u0a01-\\u0a03\\u0a3c\\u0a3e-\\u0a42\\u0a47\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a66-\\u0a71\\u0a75\\u0a81-\\u0a83\\u0abc\\u0abe-\\u0ac5\\u0ac7-\\u0ac9\\u0acb-\\u0acd\\u0ae2\\u0ae3\\u0ae6-\\u0aef\\u0afa-\\u0aff\\u0b01-\\u0b03\\u0b3c\\u0b3e-\\u0b44\\u0b47\\u0b48\\u0b4b-\\u0b4d\\u0b55-\\u0b57\\u0b62\\u0b63\\u0b66-\\u0b6f\\u0b82\\u0bbe-\\u0bc2\\u0bc6-\\u0bc8\\u0bca-\\u0bcd\\u0bd7\\u0be6-\\u0bef\\u0c00-\\u0c04\\u0c3c\\u0c3e-\\u0c44\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55\\u0c56\\u0c62\\u0c63\\u0c66-\\u0c6f\\u0c81-\\u0c83\\u0cbc\\u0cbe-\\u0cc4\\u0cc6-\\u0cc8\\u0cca-\\u0ccd\\u0cd5\\u0cd6\\u0ce2\\u0ce3\\u0ce6-\\u0cef\\u0cf3\\u0d00-\\u0d03\\u0d3b\\u0d3c\\u0d3e-\\u0d44\\u0d46-\\u0d48\\u0d4a-\\u0d4d\\u0d57\\u0d62\\u0d63\\u0d66-\\u0d6f\\u0d81-\\u0d83\\u0dca\\u0dcf-\\u0dd4\\u0dd6\\u0dd8-\\u0ddf\\u0de6-\\u0def\\u0df2\\u0df3\\u0e31\\u0e34-\\u0e3a\\u0e47-\\u0e4e\\u0e50-\\u0e59\\u0eb1\\u0eb4-\\u0ebc\\u0ec8-\\u0ece\\u0ed0-\\u0ed9\\u0f18\\u0f19\\u0f20-\\u0f29\\u0f35\\u0f37\\u0f39\\u0f3e\\u0f3f\\u0f71-\\u0f84\\u0f86\\u0f87\\u0f8d-\\u0f97\\u0f99-\\u0fbc\\u0fc6\\u102b-\\u103e\\u1040-\\u1049\\u1056-\\u1059\\u105e-\\u1060\\u1062-\\u1064\\u1067-\\u106d\\u1071-\\u1074\\u1082-\\u108d\\u108f-\\u109d\\u135d-\\u135f\\u1369-\\u1371\\u1712-\\u1715\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17b4-\\u17d3\\u17dd\\u17e0-\\u17e9\\u180b-\\u180d\\u180f-\\u1819\\u18a9\\u1920-\\u192b\\u1930-\\u193b\\u1946-\\u194f\\u19d0-\\u19da\\u1a17-\\u1a1b\\u1a55-\\u1a5e\\u1a60-\\u1a7c\\u1a7f-\\u1a89\\u1a90-\\u1a99\\u1ab0-\\u1abd\\u1abf-\\u1ace\\u1b00-\\u1b04\\u1b34-\\u1b44\\u1b50-\\u1b59\\u1b6b-\\u1b73\\u1b80-\\u1b82\\u1ba1-\\u1bad\\u1bb0-\\u1bb9\\u1be6-\\u1bf3\\u1c24-\\u1c37\\u1c40-\\u1c49\\u1c50-\\u1c59\\u1cd0-\\u1cd2\\u1cd4-\\u1ce8\\u1ced\\u1cf4\\u1cf7-\\u1cf9\\u1dc0-\\u1dff\\u203f\\u2040\\u2054\\u20d0-\\u20dc\\u20e1\\u20e5-\\u20f0\\u2cef-\\u2cf1\\u2d7f\\u2de0-\\u2dff\\u302a-\\u302f\\u3099\\u309a\\ua620-\\ua629\\ua66f\\ua674-\\ua67d\\ua69e\\ua69f\\ua6f0\\ua6f1\\ua802\\ua806\\ua80b\\ua823-\\ua827\\ua82c\\ua880\\ua881\\ua8b4-\\ua8c5\\ua8d0-\\ua8d9\\ua8e0-\\ua8f1\\ua8ff-\\ua909\\ua926-\\ua92d\\ua947-\\ua953\\ua980-\\ua983\\ua9b3-\\ua9c0\\ua9d0-\\ua9d9\\ua9e5\\ua9f0-\\ua9f9\\uaa29-\\uaa36\\uaa43\\uaa4c\\uaa4d\\uaa50-\\uaa59\\uaa7b-\\uaa7d\\uaab0\\uaab2-\\uaab4\\uaab7\\uaab8\\uaabe\\uaabf\\uaac1\\uaaeb-\\uaaef\\uaaf5\\uaaf6\\uabe3-\\uabea\\uabec\\uabed\\uabf0-\\uabf9\\ufb1e\\ufe00-\\ufe0f\\ufe20-\\ufe2f\\ufe33\\ufe34\\ufe4d-\\ufe4f\\uff10-\\uff19\\uff3f\";\n\n// This file was generated. Do not modify manually!\nvar nonASCIIidentifierStartChars = \"\\xaa\\xb5\\xba\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\u02c1\\u02c6-\\u02d1\\u02e0-\\u02e4\\u02ec\\u02ee\\u0370-\\u0374\\u0376\\u0377\\u037a-\\u037d\\u037f\\u0386\\u0388-\\u038a\\u038c\\u038e-\\u03a1\\u03a3-\\u03f5\\u03f7-\\u0481\\u048a-\\u052f\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05d0-\\u05ea\\u05ef-\\u05f2\\u0620-\\u064a\\u066e\\u066f\\u0671-\\u06d3\\u06d5\\u06e5\\u06e6\\u06ee\\u06ef\\u06fa-\\u06fc\\u06ff\\u0710\\u0712-\\u072f\\u074d-\\u07a5\\u07b1\\u07ca-\\u07ea\\u07f4\\u07f5\\u07fa\\u0800-\\u0815\\u081a\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086a\\u0870-\\u0887\\u0889-\\u088e\\u08a0-\\u08c9\\u0904-\\u0939\\u093d\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098c\\u098f\\u0990\\u0993-\\u09a8\\u09aa-\\u09b0\\u09b2\\u09b6-\\u09b9\\u09bd\\u09ce\\u09dc\\u09dd\\u09df-\\u09e1\\u09f0\\u09f1\\u09fc\\u0a05-\\u0a0a\\u0a0f\\u0a10\\u0a13-\\u0a28\\u0a2a-\\u0a30\\u0a32\\u0a33\\u0a35\\u0a36\\u0a38\\u0a39\\u0a59-\\u0a5c\\u0a5e\\u0a72-\\u0a74\\u0a85-\\u0a8d\\u0a8f-\\u0a91\\u0a93-\\u0aa8\\u0aaa-\\u0ab0\\u0ab2\\u0ab3\\u0ab5-\\u0ab9\\u0abd\\u0ad0\\u0ae0\\u0ae1\\u0af9\\u0b05-\\u0b0c\\u0b0f\\u0b10\\u0b13-\\u0b28\\u0b2a-\\u0b30\\u0b32\\u0b33\\u0b35-\\u0b39\\u0b3d\\u0b5c\\u0b5d\\u0b5f-\\u0b61\\u0b71\\u0b83\\u0b85-\\u0b8a\\u0b8e-\\u0b90\\u0b92-\\u0b95\\u0b99\\u0b9a\\u0b9c\\u0b9e\\u0b9f\\u0ba3\\u0ba4\\u0ba8-\\u0baa\\u0bae-\\u0bb9\\u0bd0\\u0c05-\\u0c0c\\u0c0e-\\u0c10\\u0c12-\\u0c28\\u0c2a-\\u0c39\\u0c3d\\u0c58-\\u0c5a\\u0c5d\\u0c60\\u0c61\\u0c80\\u0c85-\\u0c8c\\u0c8e-\\u0c90\\u0c92-\\u0ca8\\u0caa-\\u0cb3\\u0cb5-\\u0cb9\\u0cbd\\u0cdd\\u0cde\\u0ce0\\u0ce1\\u0cf1\\u0cf2\\u0d04-\\u0d0c\\u0d0e-\\u0d10\\u0d12-\\u0d3a\\u0d3d\\u0d4e\\u0d54-\\u0d56\\u0d5f-\\u0d61\\u0d7a-\\u0d7f\\u0d85-\\u0d96\\u0d9a-\\u0db1\\u0db3-\\u0dbb\\u0dbd\\u0dc0-\\u0dc6\\u0e01-\\u0e30\\u0e32\\u0e33\\u0e40-\\u0e46\\u0e81\\u0e82\\u0e84\\u0e86-\\u0e8a\\u0e8c-\\u0ea3\\u0ea5\\u0ea7-\\u0eb0\\u0eb2\\u0eb3\\u0ebd\\u0ec0-\\u0ec4\\u0ec6\\u0edc-\\u0edf\\u0f00\\u0f40-\\u0f47\\u0f49-\\u0f6c\\u0f88-\\u0f8c\\u1000-\\u102a\\u103f\\u1050-\\u1055\\u105a-\\u105d\\u1061\\u1065\\u1066\\u106e-\\u1070\\u1075-\\u1081\\u108e\\u10a0-\\u10c5\\u10c7\\u10cd\\u10d0-\\u10fa\\u10fc-\\u1248\\u124a-\\u124d\\u1250-\\u1256\\u1258\\u125a-\\u125d\\u1260-\\u1288\\u128a-\\u128d\\u1290-\\u12b0\\u12b2-\\u12b5\\u12b8-\\u12be\\u12c0\\u12c2-\\u12c5\\u12c8-\\u12d6\\u12d8-\\u1310\\u1312-\\u1315\\u1318-\\u135a\\u1380-\\u138f\\u13a0-\\u13f5\\u13f8-\\u13fd\\u1401-\\u166c\\u166f-\\u167f\\u1681-\\u169a\\u16a0-\\u16ea\\u16ee-\\u16f8\\u1700-\\u1711\\u171f-\\u1731\\u1740-\\u1751\\u1760-\\u176c\\u176e-\\u1770\\u1780-\\u17b3\\u17d7\\u17dc\\u1820-\\u1878\\u1880-\\u18a8\\u18aa\\u18b0-\\u18f5\\u1900-\\u191e\\u1950-\\u196d\\u1970-\\u1974\\u1980-\\u19ab\\u19b0-\\u19c9\\u1a00-\\u1a16\\u1a20-\\u1a54\\u1aa7\\u1b05-\\u1b33\\u1b45-\\u1b4c\\u1b83-\\u1ba0\\u1bae\\u1baf\\u1bba-\\u1be5\\u1c00-\\u1c23\\u1c4d-\\u1c4f\\u1c5a-\\u1c7d\\u1c80-\\u1c88\\u1c90-\\u1cba\\u1cbd-\\u1cbf\\u1ce9-\\u1cec\\u1cee-\\u1cf3\\u1cf5\\u1cf6\\u1cfa\\u1d00-\\u1dbf\\u1e00-\\u1f15\\u1f18-\\u1f1d\\u1f20-\\u1f45\\u1f48-\\u1f4d\\u1f50-\\u1f57\\u1f59\\u1f5b\\u1f5d\\u1f5f-\\u1f7d\\u1f80-\\u1fb4\\u1fb6-\\u1fbc\\u1fbe\\u1fc2-\\u1fc4\\u1fc6-\\u1fcc\\u1fd0-\\u1fd3\\u1fd6-\\u1fdb\\u1fe0-\\u1fec\\u1ff2-\\u1ff4\\u1ff6-\\u1ffc\\u2071\\u207f\\u2090-\\u209c\\u2102\\u2107\\u210a-\\u2113\\u2115\\u2118-\\u211d\\u2124\\u2126\\u2128\\u212a-\\u2139\\u213c-\\u213f\\u2145-\\u2149\\u214e\\u2160-\\u2188\\u2c00-\\u2ce4\\u2ceb-\\u2cee\\u2cf2\\u2cf3\\u2d00-\\u2d25\\u2d27\\u2d2d\\u2d30-\\u2d67\\u2d6f\\u2d80-\\u2d96\\u2da0-\\u2da6\\u2da8-\\u2dae\\u2db0-\\u2db6\\u2db8-\\u2dbe\\u2dc0-\\u2dc6\\u2dc8-\\u2dce\\u2dd0-\\u2dd6\\u2dd8-\\u2dde\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303c\\u3041-\\u3096\\u309b-\\u309f\\u30a1-\\u30fa\\u30fc-\\u30ff\\u3105-\\u312f\\u3131-\\u318e\\u31a0-\\u31bf\\u31f0-\\u31ff\\u3400-\\u4dbf\\u4e00-\\ua48c\\ua4d0-\\ua4fd\\ua500-\\ua60c\\ua610-\\ua61f\\ua62a\\ua62b\\ua640-\\ua66e\\ua67f-\\ua69d\\ua6a0-\\ua6ef\\ua717-\\ua71f\\ua722-\\ua788\\ua78b-\\ua7ca\\ua7d0\\ua7d1\\ua7d3\\ua7d5-\\ua7d9\\ua7f2-\\ua801\\ua803-\\ua805\\ua807-\\ua80a\\ua80c-\\ua822\\ua840-\\ua873\\ua882-\\ua8b3\\ua8f2-\\ua8f7\\ua8fb\\ua8fd\\ua8fe\\ua90a-\\ua925\\ua930-\\ua946\\ua960-\\ua97c\\ua984-\\ua9b2\\ua9cf\\ua9e0-\\ua9e4\\ua9e6-\\ua9ef\\ua9fa-\\ua9fe\\uaa00-\\uaa28\\uaa40-\\uaa42\\uaa44-\\uaa4b\\uaa60-\\uaa76\\uaa7a\\uaa7e-\\uaaaf\\uaab1\\uaab5\\uaab6\\uaab9-\\uaabd\\uaac0\\uaac2\\uaadb-\\uaadd\\uaae0-\\uaaea\\uaaf2-\\uaaf4\\uab01-\\uab06\\uab09-\\uab0e\\uab11-\\uab16\\uab20-\\uab26\\uab28-\\uab2e\\uab30-\\uab5a\\uab5c-\\uab69\\uab70-\\uabe2\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\uf900-\\ufa6d\\ufa70-\\ufad9\\ufb00-\\ufb06\\ufb13-\\ufb17\\ufb1d\\ufb1f-\\ufb28\\ufb2a-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40\\ufb41\\ufb43\\ufb44\\ufb46-\\ufbb1\\ufbd3-\\ufd3d\\ufd50-\\ufd8f\\ufd92-\\ufdc7\\ufdf0-\\ufdfb\\ufe70-\\ufe74\\ufe76-\\ufefc\\uff21-\\uff3a\\uff41-\\uff5a\\uff66-\\uffbe\\uffc2-\\uffc7\\uffca-\\uffcf\\uffd2-\\uffd7\\uffda-\\uffdc\";\n\n// These are a run-length and offset encoded representation of the\n\n// Reserved word lists for various dialects of the language\n\nvar reservedWords = {\n 3: \"abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile\",\n 5: \"class enum extends super const export import\",\n 6: \"enum\",\n strict: \"implements interface let package private protected public static yield\",\n strictBind: \"eval arguments\"\n};\n\n// And the keywords\n\nvar ecma5AndLessKeywords = \"break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this\";\n\nvar keywords$1 = {\n 5: ecma5AndLessKeywords,\n \"5module\": ecma5AndLessKeywords + \" export import\",\n 6: ecma5AndLessKeywords + \" const class extends export import super\"\n};\n\nvar keywordRelationalOperator = /^in(stanceof)?$/;\n\n// ## Character categories\n\nvar nonASCIIidentifierStart = new RegExp(\"[\" + nonASCIIidentifierStartChars + \"]\");\nvar nonASCIIidentifier = new RegExp(\"[\" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + \"]\");\n\n// This has a complexity linear to the value of the code. The\n// assumption is that looking up astral identifier characters is\n// rare.\nfunction isInAstralSet(code, set) {\n var pos = 0x10000;\n for (var i = 0; i < set.length; i += 2) {\n pos += set[i];\n if (pos > code) { return false }\n pos += set[i + 1];\n if (pos >= code) { return true }\n }\n return false\n}\n\n// Test whether a given character code starts an identifier.\n\nfunction isIdentifierStart(code, astral) {\n if (code < 65) { return code === 36 }\n if (code < 91) { return true }\n if (code < 97) { return code === 95 }\n if (code < 123) { return true }\n if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }\n if (astral === false) { return false }\n return isInAstralSet(code, astralIdentifierStartCodes)\n}\n\n// Test whether a given character is part of an identifier.\n\nfunction isIdentifierChar(code, astral) {\n if (code < 48) { return code === 36 }\n if (code < 58) { return true }\n if (code < 65) { return false }\n if (code < 91) { return true }\n if (code < 97) { return code === 95 }\n if (code < 123) { return true }\n if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }\n if (astral === false) { return false }\n return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)\n}\n\n// ## Token types\n\n// The assignment of fine-grained, information-carrying type objects\n// allows the tokenizer to store the information it has about a\n// token in a way that is very cheap for the parser to look up.\n\n// All token type variables start with an underscore, to make them\n// easy to recognize.\n\n// The `beforeExpr` property is used to disambiguate between regular\n// expressions and divisions. It is set on all token types that can\n// be followed by an expression (thus, a slash after them would be a\n// regular expression).\n//\n// The `startsExpr` property is used to check if the token ends a\n// `yield` expression. It is set on all token types that either can\n// directly start an expression (like a quotation mark) or can\n// continue an expression (like the body of a string).\n//\n// `isLoop` marks a keyword as starting a loop, which is important\n// to know when parsing a label, in order to allow or disallow\n// continue jumps to that label.\n\nvar TokenType = function TokenType(label, conf) {\n if ( conf === void 0 ) conf = {};\n\n this.label = label;\n this.keyword = conf.keyword;\n this.beforeExpr = !!conf.beforeExpr;\n this.startsExpr = !!conf.startsExpr;\n this.isLoop = !!conf.isLoop;\n this.isAssign = !!conf.isAssign;\n this.prefix = !!conf.prefix;\n this.postfix = !!conf.postfix;\n this.binop = conf.binop || null;\n this.updateContext = null;\n};\n\nfunction binop(name, prec) {\n return new TokenType(name, {beforeExpr: true, binop: prec})\n}\nvar beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true};\n\n// Map keyword names to token types.\n\nvar keywords = {};\n\n// Succinct definitions of keyword token types\nfunction kw(name, options) {\n if ( options === void 0 ) options = {};\n\n options.keyword = name;\n return keywords[name] = new TokenType(name, options)\n}\n\nvar types$1 = {\n num: new TokenType(\"num\", startsExpr),\n regexp: new TokenType(\"regexp\", startsExpr),\n string: new TokenType(\"string\", startsExpr),\n name: new TokenType(\"name\", startsExpr),\n privateId: new TokenType(\"privateId\", startsExpr),\n eof: new TokenType(\"eof\"),\n\n // Punctuation token types.\n bracketL: new TokenType(\"[\", {beforeExpr: true, startsExpr: true}),\n bracketR: new TokenType(\"]\"),\n braceL: new TokenType(\"{\", {beforeExpr: true, startsExpr: true}),\n braceR: new TokenType(\"}\"),\n parenL: new TokenType(\"(\", {beforeExpr: true, startsExpr: true}),\n parenR: new TokenType(\")\"),\n comma: new TokenType(\",\", beforeExpr),\n semi: new TokenType(\";\", beforeExpr),\n colon: new TokenType(\":\", beforeExpr),\n dot: new TokenType(\".\"),\n question: new TokenType(\"?\", beforeExpr),\n questionDot: new TokenType(\"?.\"),\n arrow: new TokenType(\"=>\", beforeExpr),\n template: new TokenType(\"template\"),\n invalidTemplate: new TokenType(\"invalidTemplate\"),\n ellipsis: new TokenType(\"...\", beforeExpr),\n backQuote: new TokenType(\"`\", startsExpr),\n dollarBraceL: new TokenType(\"${\", {beforeExpr: true, startsExpr: true}),\n\n // Operators. These carry several kinds of properties to help the\n // parser use them properly (the presence of these properties is\n // what categorizes them as operators).\n //\n // `binop`, when present, specifies that this operator is a binary\n // operator, and will refer to its precedence.\n //\n // `prefix` and `postfix` mark the operator as a prefix or postfix\n // unary operator.\n //\n // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as\n // binary operators with a very low precedence, that should result\n // in AssignmentExpression nodes.\n\n eq: new TokenType(\"=\", {beforeExpr: true, isAssign: true}),\n assign: new TokenType(\"_=\", {beforeExpr: true, isAssign: true}),\n incDec: new TokenType(\"++/--\", {prefix: true, postfix: true, startsExpr: true}),\n prefix: new TokenType(\"!/~\", {beforeExpr: true, prefix: true, startsExpr: true}),\n logicalOR: binop(\"||\", 1),\n logicalAND: binop(\"&&\", 2),\n bitwiseOR: binop(\"|\", 3),\n bitwiseXOR: binop(\"^\", 4),\n bitwiseAND: binop(\"&\", 5),\n equality: binop(\"==/!=/===/!==\", 6),\n relational: binop(\"/<=/>=\", 7),\n bitShift: binop(\"<>/>>>\", 8),\n plusMin: new TokenType(\"+/-\", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),\n modulo: binop(\"%\", 10),\n star: binop(\"*\", 10),\n slash: binop(\"/\", 10),\n starstar: new TokenType(\"**\", {beforeExpr: true}),\n coalesce: binop(\"??\", 1),\n\n // Keyword token types.\n _break: kw(\"break\"),\n _case: kw(\"case\", beforeExpr),\n _catch: kw(\"catch\"),\n _continue: kw(\"continue\"),\n _debugger: kw(\"debugger\"),\n _default: kw(\"default\", beforeExpr),\n _do: kw(\"do\", {isLoop: true, beforeExpr: true}),\n _else: kw(\"else\", beforeExpr),\n _finally: kw(\"finally\"),\n _for: kw(\"for\", {isLoop: true}),\n _function: kw(\"function\", startsExpr),\n _if: kw(\"if\"),\n _return: kw(\"return\", beforeExpr),\n _switch: kw(\"switch\"),\n _throw: kw(\"throw\", beforeExpr),\n _try: kw(\"try\"),\n _var: kw(\"var\"),\n _const: kw(\"const\"),\n _while: kw(\"while\", {isLoop: true}),\n _with: kw(\"with\"),\n _new: kw(\"new\", {beforeExpr: true, startsExpr: true}),\n _this: kw(\"this\", startsExpr),\n _super: kw(\"super\", startsExpr),\n _class: kw(\"class\", startsExpr),\n _extends: kw(\"extends\", beforeExpr),\n _export: kw(\"export\"),\n _import: kw(\"import\", startsExpr),\n _null: kw(\"null\", startsExpr),\n _true: kw(\"true\", startsExpr),\n _false: kw(\"false\", startsExpr),\n _in: kw(\"in\", {beforeExpr: true, binop: 7}),\n _instanceof: kw(\"instanceof\", {beforeExpr: true, binop: 7}),\n _typeof: kw(\"typeof\", {beforeExpr: true, prefix: true, startsExpr: true}),\n _void: kw(\"void\", {beforeExpr: true, prefix: true, startsExpr: true}),\n _delete: kw(\"delete\", {beforeExpr: true, prefix: true, startsExpr: true})\n};\n\n// Matches a whole line break (where CRLF is considered a single\n// line break). Used to count lines.\n\nvar lineBreak = /\\r\\n?|\\n|\\u2028|\\u2029/;\nvar lineBreakG = new RegExp(lineBreak.source, \"g\");\n\nfunction isNewLine(code) {\n return code === 10 || code === 13 || code === 0x2028 || code === 0x2029\n}\n\nfunction nextLineBreak(code, from, end) {\n if ( end === void 0 ) end = code.length;\n\n for (var i = from; i < end; i++) {\n var next = code.charCodeAt(i);\n if (isNewLine(next))\n { return i < end - 1 && next === 13 && code.charCodeAt(i + 1) === 10 ? i + 2 : i + 1 }\n }\n return -1\n}\n\nvar nonASCIIwhitespace = /[\\u1680\\u2000-\\u200a\\u202f\\u205f\\u3000\\ufeff]/;\n\nvar skipWhiteSpace = /(?:\\s|\\/\\/.*|\\/\\*[^]*?\\*\\/)*/g;\n\nvar ref = Object.prototype;\nvar hasOwnProperty = ref.hasOwnProperty;\nvar toString = ref.toString;\n\nvar hasOwn = Object.hasOwn || (function (obj, propName) { return (\n hasOwnProperty.call(obj, propName)\n); });\n\nvar isArray = Array.isArray || (function (obj) { return (\n toString.call(obj) === \"[object Array]\"\n); });\n\nfunction wordsRegexp(words) {\n return new RegExp(\"^(?:\" + words.replace(/ /g, \"|\") + \")$\")\n}\n\nfunction codePointToString(code) {\n // UTF-16 Decoding\n if (code <= 0xFFFF) { return String.fromCharCode(code) }\n code -= 0x10000;\n return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)\n}\n\nvar loneSurrogate = /(?:[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])/;\n\n// These are used when `options.locations` is on, for the\n// `startLoc` and `endLoc` properties.\n\nvar Position = function Position(line, col) {\n this.line = line;\n this.column = col;\n};\n\nPosition.prototype.offset = function offset (n) {\n return new Position(this.line, this.column + n)\n};\n\nvar SourceLocation = function SourceLocation(p, start, end) {\n this.start = start;\n this.end = end;\n if (p.sourceFile !== null) { this.source = p.sourceFile; }\n};\n\n// The `getLineInfo` function is mostly useful when the\n// `locations` option is off (for performance reasons) and you\n// want to find the line/column position for a given character\n// offset. `input` should be the code string that the offset refers\n// into.\n\nfunction getLineInfo(input, offset) {\n for (var line = 1, cur = 0;;) {\n var nextBreak = nextLineBreak(input, cur, offset);\n if (nextBreak < 0) { return new Position(line, offset - cur) }\n ++line;\n cur = nextBreak;\n }\n}\n\n// A second argument must be given to configure the parser process.\n// These options are recognized (only `ecmaVersion` is required):\n\nvar defaultOptions = {\n // `ecmaVersion` indicates the ECMAScript version to parse. Must be\n // either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10\n // (2019), 11 (2020), 12 (2021), 13 (2022), 14 (2023), or `\"latest\"`\n // (the latest version the library supports). This influences\n // support for strict mode, the set of reserved words, and support\n // for new syntax features.\n ecmaVersion: null,\n // `sourceType` indicates the mode the code should be parsed in.\n // Can be either `\"script\"` or `\"module\"`. This influences global\n // strict mode and parsing of `import` and `export` declarations.\n sourceType: \"script\",\n // `onInsertedSemicolon` can be a callback that will be called\n // when a semicolon is automatically inserted. It will be passed\n // the position of the comma as an offset, and if `locations` is\n // enabled, it is given the location as a `{line, column}` object\n // as second argument.\n onInsertedSemicolon: null,\n // `onTrailingComma` is similar to `onInsertedSemicolon`, but for\n // trailing commas.\n onTrailingComma: null,\n // By default, reserved words are only enforced if ecmaVersion >= 5.\n // Set `allowReserved` to a boolean value to explicitly turn this on\n // an off. When this option has the value \"never\", reserved words\n // and keywords can also not be used as property names.\n allowReserved: null,\n // When enabled, a return at the top level is not considered an\n // error.\n allowReturnOutsideFunction: false,\n // When enabled, import/export statements are not constrained to\n // appearing at the top of the program, and an import.meta expression\n // in a script isn't considered an error.\n allowImportExportEverywhere: false,\n // By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022.\n // When enabled, await identifiers are allowed to appear at the top-level scope,\n // but they are still not allowed in non-async functions.\n allowAwaitOutsideFunction: null,\n // When enabled, super identifiers are not constrained to\n // appearing in methods and do not raise an error when they appear elsewhere.\n allowSuperOutsideMethod: null,\n // When enabled, hashbang directive in the beginning of file is\n // allowed and treated as a line comment. Enabled by default when\n // `ecmaVersion` >= 2023.\n allowHashBang: false,\n // When `locations` is on, `loc` properties holding objects with\n // `start` and `end` properties in `{line, column}` form (with\n // line being 1-based and column 0-based) will be attached to the\n // nodes.\n locations: false,\n // A function can be passed as `onToken` option, which will\n // cause Acorn to call that function with object in the same\n // format as tokens returned from `tokenizer().getToken()`. Note\n // that you are not allowed to call the parser from the\n // callback—that will corrupt its internal state.\n onToken: null,\n // A function can be passed as `onComment` option, which will\n // cause Acorn to call that function with `(block, text, start,\n // end)` parameters whenever a comment is skipped. `block` is a\n // boolean indicating whether this is a block (`/* */`) comment,\n // `text` is the content of the comment, and `start` and `end` are\n // character offsets that denote the start and end of the comment.\n // When the `locations` option is on, two more parameters are\n // passed, the full `{line, column}` locations of the start and\n // end of the comments. Note that you are not allowed to call the\n // parser from the callback—that will corrupt its internal state.\n onComment: null,\n // Nodes have their start and end characters offsets recorded in\n // `start` and `end` properties (directly on the node, rather than\n // the `loc` object, which holds line/column data. To also add a\n // [semi-standardized][range] `range` property holding a `[start,\n // end]` array with the same numbers, set the `ranges` option to\n // `true`.\n //\n // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678\n ranges: false,\n // It is possible to parse multiple files into a single AST by\n // passing the tree produced by parsing the first file as\n // `program` option in subsequent parses. This will add the\n // toplevel forms of the parsed file to the `Program` (top) node\n // of an existing parse tree.\n program: null,\n // When `locations` is on, you can pass this to record the source\n // file in every node's `loc` object.\n sourceFile: null,\n // This value, if given, is stored in every node, whether\n // `locations` is on or off.\n directSourceFile: null,\n // When enabled, parenthesized expressions are represented by\n // (non-standard) ParenthesizedExpression nodes\n preserveParens: false\n};\n\n// Interpret and default an options object\n\nvar warnedAboutEcmaVersion = false;\n\nfunction getOptions(opts) {\n var options = {};\n\n for (var opt in defaultOptions)\n { options[opt] = opts && hasOwn(opts, opt) ? opts[opt] : defaultOptions[opt]; }\n\n if (options.ecmaVersion === \"latest\") {\n options.ecmaVersion = 1e8;\n } else if (options.ecmaVersion == null) {\n if (!warnedAboutEcmaVersion && typeof console === \"object\" && console.warn) {\n warnedAboutEcmaVersion = true;\n console.warn(\"Since Acorn 8.0.0, options.ecmaVersion is required.\\nDefaulting to 2020, but this will stop working in the future.\");\n }\n options.ecmaVersion = 11;\n } else if (options.ecmaVersion >= 2015) {\n options.ecmaVersion -= 2009;\n }\n\n if (options.allowReserved == null)\n { options.allowReserved = options.ecmaVersion < 5; }\n\n if (!opts || opts.allowHashBang == null)\n { options.allowHashBang = options.ecmaVersion >= 14; }\n\n if (isArray(options.onToken)) {\n var tokens = options.onToken;\n options.onToken = function (token) { return tokens.push(token); };\n }\n if (isArray(options.onComment))\n { options.onComment = pushComment(options, options.onComment); }\n\n return options\n}\n\nfunction pushComment(options, array) {\n return function(block, text, start, end, startLoc, endLoc) {\n var comment = {\n type: block ? \"Block\" : \"Line\",\n value: text,\n start: start,\n end: end\n };\n if (options.locations)\n { comment.loc = new SourceLocation(this, startLoc, endLoc); }\n if (options.ranges)\n { comment.range = [start, end]; }\n array.push(comment);\n }\n}\n\n// Each scope gets a bitset that may contain these flags\nvar\n SCOPE_TOP = 1,\n SCOPE_FUNCTION = 2,\n SCOPE_ASYNC = 4,\n SCOPE_GENERATOR = 8,\n SCOPE_ARROW = 16,\n SCOPE_SIMPLE_CATCH = 32,\n SCOPE_SUPER = 64,\n SCOPE_DIRECT_SUPER = 128,\n SCOPE_CLASS_STATIC_BLOCK = 256,\n SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK;\n\nfunction functionFlags(async, generator) {\n return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0)\n}\n\n// Used in checkLVal* and declareName to determine the type of a binding\nvar\n BIND_NONE = 0, // Not a binding\n BIND_VAR = 1, // Var-style binding\n BIND_LEXICAL = 2, // Let- or const-style binding\n BIND_FUNCTION = 3, // Function declaration\n BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding\n BIND_OUTSIDE = 5; // Special case for function names as bound inside the function\n\nvar Parser = function Parser(options, input, startPos) {\n this.options = options = getOptions(options);\n this.sourceFile = options.sourceFile;\n this.keywords = wordsRegexp(keywords$1[options.ecmaVersion >= 6 ? 6 : options.sourceType === \"module\" ? \"5module\" : 5]);\n var reserved = \"\";\n if (options.allowReserved !== true) {\n reserved = reservedWords[options.ecmaVersion >= 6 ? 6 : options.ecmaVersion === 5 ? 5 : 3];\n if (options.sourceType === \"module\") { reserved += \" await\"; }\n }\n this.reservedWords = wordsRegexp(reserved);\n var reservedStrict = (reserved ? reserved + \" \" : \"\") + reservedWords.strict;\n this.reservedWordsStrict = wordsRegexp(reservedStrict);\n this.reservedWordsStrictBind = wordsRegexp(reservedStrict + \" \" + reservedWords.strictBind);\n this.input = String(input);\n\n // Used to signal to callers of `readWord1` whether the word\n // contained any escape sequences. This is needed because words with\n // escape sequences must not be interpreted as keywords.\n this.containsEsc = false;\n\n // Set up token state\n\n // The current position of the tokenizer in the input.\n if (startPos) {\n this.pos = startPos;\n this.lineStart = this.input.lastIndexOf(\"\\n\", startPos - 1) + 1;\n this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;\n } else {\n this.pos = this.lineStart = 0;\n this.curLine = 1;\n }\n\n // Properties of the current token:\n // Its type\n this.type = types$1.eof;\n // For tokens that include more information than their type, the value\n this.value = null;\n // Its start and end offset\n this.start = this.end = this.pos;\n // And, if locations are used, the {line, column} object\n // corresponding to those offsets\n this.startLoc = this.endLoc = this.curPosition();\n\n // Position information for the previous token\n this.lastTokEndLoc = this.lastTokStartLoc = null;\n this.lastTokStart = this.lastTokEnd = this.pos;\n\n // The context stack is used to superficially track syntactic\n // context to predict whether a regular expression is allowed in a\n // given position.\n this.context = this.initialContext();\n this.exprAllowed = true;\n\n // Figure out if it's a module code.\n this.inModule = options.sourceType === \"module\";\n this.strict = this.inModule || this.strictDirective(this.pos);\n\n // Used to signify the start of a potential arrow function\n this.potentialArrowAt = -1;\n this.potentialArrowInForAwait = false;\n\n // Positions to delayed-check that yield/await does not exist in default parameters.\n this.yieldPos = this.awaitPos = this.awaitIdentPos = 0;\n // Labels in scope.\n this.labels = [];\n // Thus-far undefined exports.\n this.undefinedExports = Object.create(null);\n\n // If enabled, skip leading hashbang line.\n if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === \"#!\")\n { this.skipLineComment(2); }\n\n // Scope tracking for duplicate variable names (see scope.js)\n this.scopeStack = [];\n this.enterScope(SCOPE_TOP);\n\n // For RegExp validation\n this.regexpState = null;\n\n // The stack of private names.\n // Each element has two properties: 'declared' and 'used'.\n // When it exited from the outermost class definition, all used private names must be declared.\n this.privateNameStack = [];\n};\n\nvar prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },allowNewDotTarget: { configurable: true },inClassStaticBlock: { configurable: true } };\n\nParser.prototype.parse = function parse () {\n var node = this.options.program || this.startNode();\n this.nextToken();\n return this.parseTopLevel(node)\n};\n\nprototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 };\n\nprototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 && !this.currentVarScope().inClassFieldInit };\n\nprototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 && !this.currentVarScope().inClassFieldInit };\n\nprototypeAccessors.canAwait.get = function () {\n for (var i = this.scopeStack.length - 1; i >= 0; i--) {\n var scope = this.scopeStack[i];\n if (scope.inClassFieldInit || scope.flags & SCOPE_CLASS_STATIC_BLOCK) { return false }\n if (scope.flags & SCOPE_FUNCTION) { return (scope.flags & SCOPE_ASYNC) > 0 }\n }\n return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction\n};\n\nprototypeAccessors.allowSuper.get = function () {\n var ref = this.currentThisScope();\n var flags = ref.flags;\n var inClassFieldInit = ref.inClassFieldInit;\n return (flags & SCOPE_SUPER) > 0 || inClassFieldInit || this.options.allowSuperOutsideMethod\n};\n\nprototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 };\n\nprototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) };\n\nprototypeAccessors.allowNewDotTarget.get = function () {\n var ref = this.currentThisScope();\n var flags = ref.flags;\n var inClassFieldInit = ref.inClassFieldInit;\n return (flags & (SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK)) > 0 || inClassFieldInit\n};\n\nprototypeAccessors.inClassStaticBlock.get = function () {\n return (this.currentVarScope().flags & SCOPE_CLASS_STATIC_BLOCK) > 0\n};\n\nParser.extend = function extend () {\n var plugins = [], len = arguments.length;\n while ( len-- ) plugins[ len ] = arguments[ len ];\n\n var cls = this;\n for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); }\n return cls\n};\n\nParser.parse = function parse (input, options) {\n return new this(options, input).parse()\n};\n\nParser.parseExpressionAt = function parseExpressionAt (input, pos, options) {\n var parser = new this(options, input, pos);\n parser.nextToken();\n return parser.parseExpression()\n};\n\nParser.tokenizer = function tokenizer (input, options) {\n return new this(options, input)\n};\n\nObject.defineProperties( Parser.prototype, prototypeAccessors );\n\nvar pp$9 = Parser.prototype;\n\n// ## Parser utilities\n\nvar literal = /^(?:'((?:\\\\.|[^'\\\\])*?)'|\"((?:\\\\.|[^\"\\\\])*?)\")/;\npp$9.strictDirective = function(start) {\n if (this.options.ecmaVersion < 5) { return false }\n for (;;) {\n // Try to find string literal.\n skipWhiteSpace.lastIndex = start;\n start += skipWhiteSpace.exec(this.input)[0].length;\n var match = literal.exec(this.input.slice(start));\n if (!match) { return false }\n if ((match[1] || match[2]) === \"use strict\") {\n skipWhiteSpace.lastIndex = start + match[0].length;\n var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length;\n var next = this.input.charAt(end);\n return next === \";\" || next === \"}\" ||\n (lineBreak.test(spaceAfter[0]) &&\n !(/[(`.[+\\-/*%<>=,?^&]/.test(next) || next === \"!\" && this.input.charAt(end + 1) === \"=\"))\n }\n start += match[0].length;\n\n // Skip semicolon, if any.\n skipWhiteSpace.lastIndex = start;\n start += skipWhiteSpace.exec(this.input)[0].length;\n if (this.input[start] === \";\")\n { start++; }\n }\n};\n\n// Predicate that tests whether the next token is of the given\n// type, and if yes, consumes it as a side effect.\n\npp$9.eat = function(type) {\n if (this.type === type) {\n this.next();\n return true\n } else {\n return false\n }\n};\n\n// Tests whether parsed token is a contextual keyword.\n\npp$9.isContextual = function(name) {\n return this.type === types$1.name && this.value === name && !this.containsEsc\n};\n\n// Consumes contextual keyword if possible.\n\npp$9.eatContextual = function(name) {\n if (!this.isContextual(name)) { return false }\n this.next();\n return true\n};\n\n// Asserts that following token is given contextual keyword.\n\npp$9.expectContextual = function(name) {\n if (!this.eatContextual(name)) { this.unexpected(); }\n};\n\n// Test whether a semicolon can be inserted at the current position.\n\npp$9.canInsertSemicolon = function() {\n return this.type === types$1.eof ||\n this.type === types$1.braceR ||\n lineBreak.test(this.input.slice(this.lastTokEnd, this.start))\n};\n\npp$9.insertSemicolon = function() {\n if (this.canInsertSemicolon()) {\n if (this.options.onInsertedSemicolon)\n { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }\n return true\n }\n};\n\n// Consume a semicolon, or, failing that, see if we are allowed to\n// pretend that there is a semicolon at this position.\n\npp$9.semicolon = function() {\n if (!this.eat(types$1.semi) && !this.insertSemicolon()) { this.unexpected(); }\n};\n\npp$9.afterTrailingComma = function(tokType, notNext) {\n if (this.type === tokType) {\n if (this.options.onTrailingComma)\n { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }\n if (!notNext)\n { this.next(); }\n return true\n }\n};\n\n// Expect a token of a given type. If found, consume it, otherwise,\n// raise an unexpected token error.\n\npp$9.expect = function(type) {\n this.eat(type) || this.unexpected();\n};\n\n// Raise an unexpected token error.\n\npp$9.unexpected = function(pos) {\n this.raise(pos != null ? pos : this.start, \"Unexpected token\");\n};\n\nvar DestructuringErrors = function DestructuringErrors() {\n this.shorthandAssign =\n this.trailingComma =\n this.parenthesizedAssign =\n this.parenthesizedBind =\n this.doubleProto =\n -1;\n};\n\npp$9.checkPatternErrors = function(refDestructuringErrors, isAssign) {\n if (!refDestructuringErrors) { return }\n if (refDestructuringErrors.trailingComma > -1)\n { this.raiseRecoverable(refDestructuringErrors.trailingComma, \"Comma is not permitted after the rest element\"); }\n var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;\n if (parens > -1) { this.raiseRecoverable(parens, isAssign ? \"Assigning to rvalue\" : \"Parenthesized pattern\"); }\n};\n\npp$9.checkExpressionErrors = function(refDestructuringErrors, andThrow) {\n if (!refDestructuringErrors) { return false }\n var shorthandAssign = refDestructuringErrors.shorthandAssign;\n var doubleProto = refDestructuringErrors.doubleProto;\n if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }\n if (shorthandAssign >= 0)\n { this.raise(shorthandAssign, \"Shorthand property assignments are valid only in destructuring patterns\"); }\n if (doubleProto >= 0)\n { this.raiseRecoverable(doubleProto, \"Redefinition of __proto__ property\"); }\n};\n\npp$9.checkYieldAwaitInDefaultParams = function() {\n if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))\n { this.raise(this.yieldPos, \"Yield expression cannot be a default value\"); }\n if (this.awaitPos)\n { this.raise(this.awaitPos, \"Await expression cannot be a default value\"); }\n};\n\npp$9.isSimpleAssignTarget = function(expr) {\n if (expr.type === \"ParenthesizedExpression\")\n { return this.isSimpleAssignTarget(expr.expression) }\n return expr.type === \"Identifier\" || expr.type === \"MemberExpression\"\n};\n\nvar pp$8 = Parser.prototype;\n\n// ### Statement parsing\n\n// Parse a program. Initializes the parser, reads any number of\n// statements, and wraps them in a Program node. Optionally takes a\n// `program` argument. If present, the statements will be appended\n// to its body instead of creating a new node.\n\npp$8.parseTopLevel = function(node) {\n var exports = Object.create(null);\n if (!node.body) { node.body = []; }\n while (this.type !== types$1.eof) {\n var stmt = this.parseStatement(null, true, exports);\n node.body.push(stmt);\n }\n if (this.inModule)\n { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1)\n {\n var name = list[i];\n\n this.raiseRecoverable(this.undefinedExports[name].start, (\"Export '\" + name + \"' is not defined\"));\n } }\n this.adaptDirectivePrologue(node.body);\n this.next();\n node.sourceType = this.options.sourceType;\n return this.finishNode(node, \"Program\")\n};\n\nvar loopLabel = {kind: \"loop\"}, switchLabel = {kind: \"switch\"};\n\npp$8.isLet = function(context) {\n if (this.options.ecmaVersion < 6 || !this.isContextual(\"let\")) { return false }\n skipWhiteSpace.lastIndex = this.pos;\n var skip = skipWhiteSpace.exec(this.input);\n var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);\n // For ambiguous cases, determine if a LexicalDeclaration (or only a\n // Statement) is allowed here. If context is not empty then only a Statement\n // is allowed. However, `let [` is an explicit negative lookahead for\n // ExpressionStatement, so special-case it first.\n if (nextCh === 91 || nextCh === 92) { return true } // '[', '/'\n if (context) { return false }\n\n if (nextCh === 123 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '{', astral\n if (isIdentifierStart(nextCh, true)) {\n var pos = next + 1;\n while (isIdentifierChar(nextCh = this.input.charCodeAt(pos), true)) { ++pos; }\n if (nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true }\n var ident = this.input.slice(next, pos);\n if (!keywordRelationalOperator.test(ident)) { return true }\n }\n return false\n};\n\n// check 'async [no LineTerminator here] function'\n// - 'async /*foo*/ function' is OK.\n// - 'async /*\\n*/ function' is invalid.\npp$8.isAsyncFunction = function() {\n if (this.options.ecmaVersion < 8 || !this.isContextual(\"async\"))\n { return false }\n\n skipWhiteSpace.lastIndex = this.pos;\n var skip = skipWhiteSpace.exec(this.input);\n var next = this.pos + skip[0].length, after;\n return !lineBreak.test(this.input.slice(this.pos, next)) &&\n this.input.slice(next, next + 8) === \"function\" &&\n (next + 8 === this.input.length ||\n !(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00))\n};\n\n// Parse a single statement.\n//\n// If expecting a statement and finding a slash operator, parse a\n// regular expression literal. This is to handle cases like\n// `if (foo) /blah/.exec(foo)`, where looking at the previous token\n// does not help.\n\npp$8.parseStatement = function(context, topLevel, exports) {\n var starttype = this.type, node = this.startNode(), kind;\n\n if (this.isLet(context)) {\n starttype = types$1._var;\n kind = \"let\";\n }\n\n // Most types of statements are recognized by the keyword they\n // start with. Many are trivial to parse, some require a bit of\n // complexity.\n\n switch (starttype) {\n case types$1._break: case types$1._continue: return this.parseBreakContinueStatement(node, starttype.keyword)\n case types$1._debugger: return this.parseDebuggerStatement(node)\n case types$1._do: return this.parseDoStatement(node)\n case types$1._for: return this.parseForStatement(node)\n case types$1._function:\n // Function as sole body of either an if statement or a labeled statement\n // works, but not when it is part of a labeled statement that is the sole\n // body of an if statement.\n if ((context && (this.strict || context !== \"if\" && context !== \"label\")) && this.options.ecmaVersion >= 6) { this.unexpected(); }\n return this.parseFunctionStatement(node, false, !context)\n case types$1._class:\n if (context) { this.unexpected(); }\n return this.parseClass(node, true)\n case types$1._if: return this.parseIfStatement(node)\n case types$1._return: return this.parseReturnStatement(node)\n case types$1._switch: return this.parseSwitchStatement(node)\n case types$1._throw: return this.parseThrowStatement(node)\n case types$1._try: return this.parseTryStatement(node)\n case types$1._const: case types$1._var:\n kind = kind || this.value;\n if (context && kind !== \"var\") { this.unexpected(); }\n return this.parseVarStatement(node, kind)\n case types$1._while: return this.parseWhileStatement(node)\n case types$1._with: return this.parseWithStatement(node)\n case types$1.braceL: return this.parseBlock(true, node)\n case types$1.semi: return this.parseEmptyStatement(node)\n case types$1._export:\n case types$1._import:\n if (this.options.ecmaVersion > 10 && starttype === types$1._import) {\n skipWhiteSpace.lastIndex = this.pos;\n var skip = skipWhiteSpace.exec(this.input);\n var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);\n if (nextCh === 40 || nextCh === 46) // '(' or '.'\n { return this.parseExpressionStatement(node, this.parseExpression()) }\n }\n\n if (!this.options.allowImportExportEverywhere) {\n if (!topLevel)\n { this.raise(this.start, \"'import' and 'export' may only appear at the top level\"); }\n if (!this.inModule)\n { this.raise(this.start, \"'import' and 'export' may appear only with 'sourceType: module'\"); }\n }\n return starttype === types$1._import ? this.parseImport(node) : this.parseExport(node, exports)\n\n // If the statement does not start with a statement keyword or a\n // brace, it's an ExpressionStatement or LabeledStatement. We\n // simply start parsing an expression, and afterwards, if the\n // next token is a colon and the expression was a simple\n // Identifier node, we switch to interpreting it as a label.\n default:\n if (this.isAsyncFunction()) {\n if (context) { this.unexpected(); }\n this.next();\n return this.parseFunctionStatement(node, true, !context)\n }\n\n var maybeName = this.value, expr = this.parseExpression();\n if (starttype === types$1.name && expr.type === \"Identifier\" && this.eat(types$1.colon))\n { return this.parseLabeledStatement(node, maybeName, expr, context) }\n else { return this.parseExpressionStatement(node, expr) }\n }\n};\n\npp$8.parseBreakContinueStatement = function(node, keyword) {\n var isBreak = keyword === \"break\";\n this.next();\n if (this.eat(types$1.semi) || this.insertSemicolon()) { node.label = null; }\n else if (this.type !== types$1.name) { this.unexpected(); }\n else {\n node.label = this.parseIdent();\n this.semicolon();\n }\n\n // Verify that there is an actual destination to break or\n // continue to.\n var i = 0;\n for (; i < this.labels.length; ++i) {\n var lab = this.labels[i];\n if (node.label == null || lab.name === node.label.name) {\n if (lab.kind != null && (isBreak || lab.kind === \"loop\")) { break }\n if (node.label && isBreak) { break }\n }\n }\n if (i === this.labels.length) { this.raise(node.start, \"Unsyntactic \" + keyword); }\n return this.finishNode(node, isBreak ? \"BreakStatement\" : \"ContinueStatement\")\n};\n\npp$8.parseDebuggerStatement = function(node) {\n this.next();\n this.semicolon();\n return this.finishNode(node, \"DebuggerStatement\")\n};\n\npp$8.parseDoStatement = function(node) {\n this.next();\n this.labels.push(loopLabel);\n node.body = this.parseStatement(\"do\");\n this.labels.pop();\n this.expect(types$1._while);\n node.test = this.parseParenExpression();\n if (this.options.ecmaVersion >= 6)\n { this.eat(types$1.semi); }\n else\n { this.semicolon(); }\n return this.finishNode(node, \"DoWhileStatement\")\n};\n\n// Disambiguating between a `for` and a `for`/`in` or `for`/`of`\n// loop is non-trivial. Basically, we have to parse the init `var`\n// statement or expression, disallowing the `in` operator (see\n// the second parameter to `parseExpression`), and then check\n// whether the next token is `in` or `of`. When there is no init\n// part (semicolon immediately after the opening parenthesis), it\n// is a regular `for` loop.\n\npp$8.parseForStatement = function(node) {\n this.next();\n var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual(\"await\")) ? this.lastTokStart : -1;\n this.labels.push(loopLabel);\n this.enterScope(0);\n this.expect(types$1.parenL);\n if (this.type === types$1.semi) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, null)\n }\n var isLet = this.isLet();\n if (this.type === types$1._var || this.type === types$1._const || isLet) {\n var init$1 = this.startNode(), kind = isLet ? \"let\" : this.value;\n this.next();\n this.parseVar(init$1, true, kind);\n this.finishNode(init$1, \"VariableDeclaration\");\n if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual(\"of\"))) && init$1.declarations.length === 1) {\n if (this.options.ecmaVersion >= 9) {\n if (this.type === types$1._in) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n } else { node.await = awaitAt > -1; }\n }\n return this.parseForIn(node, init$1)\n }\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, init$1)\n }\n var startsWithLet = this.isContextual(\"let\"), isForOf = false;\n var refDestructuringErrors = new DestructuringErrors;\n var init = this.parseExpression(awaitAt > -1 ? \"await\" : true, refDestructuringErrors);\n if (this.type === types$1._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual(\"of\"))) {\n if (this.options.ecmaVersion >= 9) {\n if (this.type === types$1._in) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n } else { node.await = awaitAt > -1; }\n }\n if (startsWithLet && isForOf) { this.raise(init.start, \"The left-hand side of a for-of loop may not start with 'let'.\"); }\n this.toAssignable(init, false, refDestructuringErrors);\n this.checkLValPattern(init);\n return this.parseForIn(node, init)\n } else {\n this.checkExpressionErrors(refDestructuringErrors, true);\n }\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, init)\n};\n\npp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) {\n this.next();\n return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync)\n};\n\npp$8.parseIfStatement = function(node) {\n this.next();\n node.test = this.parseParenExpression();\n // allow function declarations in branches, but only in non-strict mode\n node.consequent = this.parseStatement(\"if\");\n node.alternate = this.eat(types$1._else) ? this.parseStatement(\"if\") : null;\n return this.finishNode(node, \"IfStatement\")\n};\n\npp$8.parseReturnStatement = function(node) {\n if (!this.inFunction && !this.options.allowReturnOutsideFunction)\n { this.raise(this.start, \"'return' outside of function\"); }\n this.next();\n\n // In `return` (and `break`/`continue`), the keywords with\n // optional arguments, we eagerly look for a semicolon or the\n // possibility to insert one.\n\n if (this.eat(types$1.semi) || this.insertSemicolon()) { node.argument = null; }\n else { node.argument = this.parseExpression(); this.semicolon(); }\n return this.finishNode(node, \"ReturnStatement\")\n};\n\npp$8.parseSwitchStatement = function(node) {\n this.next();\n node.discriminant = this.parseParenExpression();\n node.cases = [];\n this.expect(types$1.braceL);\n this.labels.push(switchLabel);\n this.enterScope(0);\n\n // Statements under must be grouped (by label) in SwitchCase\n // nodes. `cur` is used to keep the node that we are currently\n // adding statements to.\n\n var cur;\n for (var sawDefault = false; this.type !== types$1.braceR;) {\n if (this.type === types$1._case || this.type === types$1._default) {\n var isCase = this.type === types$1._case;\n if (cur) { this.finishNode(cur, \"SwitchCase\"); }\n node.cases.push(cur = this.startNode());\n cur.consequent = [];\n this.next();\n if (isCase) {\n cur.test = this.parseExpression();\n } else {\n if (sawDefault) { this.raiseRecoverable(this.lastTokStart, \"Multiple default clauses\"); }\n sawDefault = true;\n cur.test = null;\n }\n this.expect(types$1.colon);\n } else {\n if (!cur) { this.unexpected(); }\n cur.consequent.push(this.parseStatement(null));\n }\n }\n this.exitScope();\n if (cur) { this.finishNode(cur, \"SwitchCase\"); }\n this.next(); // Closing brace\n this.labels.pop();\n return this.finishNode(node, \"SwitchStatement\")\n};\n\npp$8.parseThrowStatement = function(node) {\n this.next();\n if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))\n { this.raise(this.lastTokEnd, \"Illegal newline after throw\"); }\n node.argument = this.parseExpression();\n this.semicolon();\n return this.finishNode(node, \"ThrowStatement\")\n};\n\n// Reused empty array added for node fields that are always empty.\n\nvar empty$1 = [];\n\npp$8.parseTryStatement = function(node) {\n this.next();\n node.block = this.parseBlock();\n node.handler = null;\n if (this.type === types$1._catch) {\n var clause = this.startNode();\n this.next();\n if (this.eat(types$1.parenL)) {\n clause.param = this.parseBindingAtom();\n var simple = clause.param.type === \"Identifier\";\n this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0);\n this.checkLValPattern(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL);\n this.expect(types$1.parenR);\n } else {\n if (this.options.ecmaVersion < 10) { this.unexpected(); }\n clause.param = null;\n this.enterScope(0);\n }\n clause.body = this.parseBlock(false);\n this.exitScope();\n node.handler = this.finishNode(clause, \"CatchClause\");\n }\n node.finalizer = this.eat(types$1._finally) ? this.parseBlock() : null;\n if (!node.handler && !node.finalizer)\n { this.raise(node.start, \"Missing catch or finally clause\"); }\n return this.finishNode(node, \"TryStatement\")\n};\n\npp$8.parseVarStatement = function(node, kind) {\n this.next();\n this.parseVar(node, false, kind);\n this.semicolon();\n return this.finishNode(node, \"VariableDeclaration\")\n};\n\npp$8.parseWhileStatement = function(node) {\n this.next();\n node.test = this.parseParenExpression();\n this.labels.push(loopLabel);\n node.body = this.parseStatement(\"while\");\n this.labels.pop();\n return this.finishNode(node, \"WhileStatement\")\n};\n\npp$8.parseWithStatement = function(node) {\n if (this.strict) { this.raise(this.start, \"'with' in strict mode\"); }\n this.next();\n node.object = this.parseParenExpression();\n node.body = this.parseStatement(\"with\");\n return this.finishNode(node, \"WithStatement\")\n};\n\npp$8.parseEmptyStatement = function(node) {\n this.next();\n return this.finishNode(node, \"EmptyStatement\")\n};\n\npp$8.parseLabeledStatement = function(node, maybeName, expr, context) {\n for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1)\n {\n var label = list[i$1];\n\n if (label.name === maybeName)\n { this.raise(expr.start, \"Label '\" + maybeName + \"' is already declared\");\n } }\n var kind = this.type.isLoop ? \"loop\" : this.type === types$1._switch ? \"switch\" : null;\n for (var i = this.labels.length - 1; i >= 0; i--) {\n var label$1 = this.labels[i];\n if (label$1.statementStart === node.start) {\n // Update information about previous labels on this node\n label$1.statementStart = this.start;\n label$1.kind = kind;\n } else { break }\n }\n this.labels.push({name: maybeName, kind: kind, statementStart: this.start});\n node.body = this.parseStatement(context ? context.indexOf(\"label\") === -1 ? context + \"label\" : context : \"label\");\n this.labels.pop();\n node.label = expr;\n return this.finishNode(node, \"LabeledStatement\")\n};\n\npp$8.parseExpressionStatement = function(node, expr) {\n node.expression = expr;\n this.semicolon();\n return this.finishNode(node, \"ExpressionStatement\")\n};\n\n// Parse a semicolon-enclosed block of statements, handling `\"use\n// strict\"` declarations when `allowStrict` is true (used for\n// function bodies).\n\npp$8.parseBlock = function(createNewLexicalScope, node, exitStrict) {\n if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;\n if ( node === void 0 ) node = this.startNode();\n\n node.body = [];\n this.expect(types$1.braceL);\n if (createNewLexicalScope) { this.enterScope(0); }\n while (this.type !== types$1.braceR) {\n var stmt = this.parseStatement(null);\n node.body.push(stmt);\n }\n if (exitStrict) { this.strict = false; }\n this.next();\n if (createNewLexicalScope) { this.exitScope(); }\n return this.finishNode(node, \"BlockStatement\")\n};\n\n// Parse a regular `for` loop. The disambiguation code in\n// `parseStatement` will already have parsed the init statement or\n// expression.\n\npp$8.parseFor = function(node, init) {\n node.init = init;\n this.expect(types$1.semi);\n node.test = this.type === types$1.semi ? null : this.parseExpression();\n this.expect(types$1.semi);\n node.update = this.type === types$1.parenR ? null : this.parseExpression();\n this.expect(types$1.parenR);\n node.body = this.parseStatement(\"for\");\n this.exitScope();\n this.labels.pop();\n return this.finishNode(node, \"ForStatement\")\n};\n\n// Parse a `for`/`in` and `for`/`of` loop, which are almost\n// same from parser's perspective.\n\npp$8.parseForIn = function(node, init) {\n var isForIn = this.type === types$1._in;\n this.next();\n\n if (\n init.type === \"VariableDeclaration\" &&\n init.declarations[0].init != null &&\n (\n !isForIn ||\n this.options.ecmaVersion < 8 ||\n this.strict ||\n init.kind !== \"var\" ||\n init.declarations[0].id.type !== \"Identifier\"\n )\n ) {\n this.raise(\n init.start,\n ((isForIn ? \"for-in\" : \"for-of\") + \" loop variable declaration may not have an initializer\")\n );\n }\n node.left = init;\n node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign();\n this.expect(types$1.parenR);\n node.body = this.parseStatement(\"for\");\n this.exitScope();\n this.labels.pop();\n return this.finishNode(node, isForIn ? \"ForInStatement\" : \"ForOfStatement\")\n};\n\n// Parse a list of variable declarations.\n\npp$8.parseVar = function(node, isFor, kind) {\n node.declarations = [];\n node.kind = kind;\n for (;;) {\n var decl = this.startNode();\n this.parseVarId(decl, kind);\n if (this.eat(types$1.eq)) {\n decl.init = this.parseMaybeAssign(isFor);\n } else if (kind === \"const\" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual(\"of\")))) {\n this.unexpected();\n } else if (decl.id.type !== \"Identifier\" && !(isFor && (this.type === types$1._in || this.isContextual(\"of\")))) {\n this.raise(this.lastTokEnd, \"Complex binding patterns require an initialization value\");\n } else {\n decl.init = null;\n }\n node.declarations.push(this.finishNode(decl, \"VariableDeclarator\"));\n if (!this.eat(types$1.comma)) { break }\n }\n return node\n};\n\npp$8.parseVarId = function(decl, kind) {\n decl.id = this.parseBindingAtom();\n this.checkLValPattern(decl.id, kind === \"var\" ? BIND_VAR : BIND_LEXICAL, false);\n};\n\nvar FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4;\n\n// Parse a function declaration or literal (depending on the\n// `statement & FUNC_STATEMENT`).\n\n// Remove `allowExpressionBody` for 7.0.0, as it is only called with false\npp$8.parseFunction = function(node, statement, allowExpressionBody, isAsync, forInit) {\n this.initFunction(node);\n if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) {\n if (this.type === types$1.star && (statement & FUNC_HANGING_STATEMENT))\n { this.unexpected(); }\n node.generator = this.eat(types$1.star);\n }\n if (this.options.ecmaVersion >= 8)\n { node.async = !!isAsync; }\n\n if (statement & FUNC_STATEMENT) {\n node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types$1.name ? null : this.parseIdent();\n if (node.id && !(statement & FUNC_HANGING_STATEMENT))\n // If it is a regular function declaration in sloppy mode, then it is\n // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding\n // mode depends on properties of the current scope (see\n // treatFunctionsAsVar).\n { this.checkLValSimple(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); }\n }\n\n var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.awaitIdentPos = 0;\n this.enterScope(functionFlags(node.async, node.generator));\n\n if (!(statement & FUNC_STATEMENT))\n { node.id = this.type === types$1.name ? this.parseIdent() : null; }\n\n this.parseFunctionParams(node);\n this.parseFunctionBody(node, allowExpressionBody, false, forInit);\n\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.awaitIdentPos = oldAwaitIdentPos;\n return this.finishNode(node, (statement & FUNC_STATEMENT) ? \"FunctionDeclaration\" : \"FunctionExpression\")\n};\n\npp$8.parseFunctionParams = function(node) {\n this.expect(types$1.parenL);\n node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8);\n this.checkYieldAwaitInDefaultParams();\n};\n\n// Parse a class declaration or literal (depending on the\n// `isStatement` parameter).\n\npp$8.parseClass = function(node, isStatement) {\n this.next();\n\n // ecma-262 14.6 Class Definitions\n // A class definition is always strict mode code.\n var oldStrict = this.strict;\n this.strict = true;\n\n this.parseClassId(node, isStatement);\n this.parseClassSuper(node);\n var privateNameMap = this.enterClassBody();\n var classBody = this.startNode();\n var hadConstructor = false;\n classBody.body = [];\n this.expect(types$1.braceL);\n while (this.type !== types$1.braceR) {\n var element = this.parseClassElement(node.superClass !== null);\n if (element) {\n classBody.body.push(element);\n if (element.type === \"MethodDefinition\" && element.kind === \"constructor\") {\n if (hadConstructor) { this.raise(element.start, \"Duplicate constructor in the same class\"); }\n hadConstructor = true;\n } else if (element.key && element.key.type === \"PrivateIdentifier\" && isPrivateNameConflicted(privateNameMap, element)) {\n this.raiseRecoverable(element.key.start, (\"Identifier '#\" + (element.key.name) + \"' has already been declared\"));\n }\n }\n }\n this.strict = oldStrict;\n this.next();\n node.body = this.finishNode(classBody, \"ClassBody\");\n this.exitClassBody();\n return this.finishNode(node, isStatement ? \"ClassDeclaration\" : \"ClassExpression\")\n};\n\npp$8.parseClassElement = function(constructorAllowsSuper) {\n if (this.eat(types$1.semi)) { return null }\n\n var ecmaVersion = this.options.ecmaVersion;\n var node = this.startNode();\n var keyName = \"\";\n var isGenerator = false;\n var isAsync = false;\n var kind = \"method\";\n var isStatic = false;\n\n if (this.eatContextual(\"static\")) {\n // Parse static init block\n if (ecmaVersion >= 13 && this.eat(types$1.braceL)) {\n this.parseClassStaticBlock(node);\n return node\n }\n if (this.isClassElementNameStart() || this.type === types$1.star) {\n isStatic = true;\n } else {\n keyName = \"static\";\n }\n }\n node.static = isStatic;\n if (!keyName && ecmaVersion >= 8 && this.eatContextual(\"async\")) {\n if ((this.isClassElementNameStart() || this.type === types$1.star) && !this.canInsertSemicolon()) {\n isAsync = true;\n } else {\n keyName = \"async\";\n }\n }\n if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types$1.star)) {\n isGenerator = true;\n }\n if (!keyName && !isAsync && !isGenerator) {\n var lastValue = this.value;\n if (this.eatContextual(\"get\") || this.eatContextual(\"set\")) {\n if (this.isClassElementNameStart()) {\n kind = lastValue;\n } else {\n keyName = lastValue;\n }\n }\n }\n\n // Parse element name\n if (keyName) {\n // 'async', 'get', 'set', or 'static' were not a keyword contextually.\n // The last token is any of those. Make it the element name.\n node.computed = false;\n node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc);\n node.key.name = keyName;\n this.finishNode(node.key, \"Identifier\");\n } else {\n this.parseClassElementName(node);\n }\n\n // Parse element value\n if (ecmaVersion < 13 || this.type === types$1.parenL || kind !== \"method\" || isGenerator || isAsync) {\n var isConstructor = !node.static && checkKeyName(node, \"constructor\");\n var allowsDirectSuper = isConstructor && constructorAllowsSuper;\n // Couldn't move this check into the 'parseClassMethod' method for backward compatibility.\n if (isConstructor && kind !== \"method\") { this.raise(node.key.start, \"Constructor can't have get/set modifier\"); }\n node.kind = isConstructor ? \"constructor\" : kind;\n this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper);\n } else {\n this.parseClassField(node);\n }\n\n return node\n};\n\npp$8.isClassElementNameStart = function() {\n return (\n this.type === types$1.name ||\n this.type === types$1.privateId ||\n this.type === types$1.num ||\n this.type === types$1.string ||\n this.type === types$1.bracketL ||\n this.type.keyword\n )\n};\n\npp$8.parseClassElementName = function(element) {\n if (this.type === types$1.privateId) {\n if (this.value === \"constructor\") {\n this.raise(this.start, \"Classes can't have an element named '#constructor'\");\n }\n element.computed = false;\n element.key = this.parsePrivateIdent();\n } else {\n this.parsePropertyName(element);\n }\n};\n\npp$8.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) {\n // Check key and flags\n var key = method.key;\n if (method.kind === \"constructor\") {\n if (isGenerator) { this.raise(key.start, \"Constructor can't be a generator\"); }\n if (isAsync) { this.raise(key.start, \"Constructor can't be an async method\"); }\n } else if (method.static && checkKeyName(method, \"prototype\")) {\n this.raise(key.start, \"Classes may not have a static property named prototype\");\n }\n\n // Parse value\n var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);\n\n // Check value\n if (method.kind === \"get\" && value.params.length !== 0)\n { this.raiseRecoverable(value.start, \"getter should have no params\"); }\n if (method.kind === \"set\" && value.params.length !== 1)\n { this.raiseRecoverable(value.start, \"setter should have exactly one param\"); }\n if (method.kind === \"set\" && value.params[0].type === \"RestElement\")\n { this.raiseRecoverable(value.params[0].start, \"Setter cannot use rest params\"); }\n\n return this.finishNode(method, \"MethodDefinition\")\n};\n\npp$8.parseClassField = function(field) {\n if (checkKeyName(field, \"constructor\")) {\n this.raise(field.key.start, \"Classes can't have a field named 'constructor'\");\n } else if (field.static && checkKeyName(field, \"prototype\")) {\n this.raise(field.key.start, \"Classes can't have a static field named 'prototype'\");\n }\n\n if (this.eat(types$1.eq)) {\n // To raise SyntaxError if 'arguments' exists in the initializer.\n var scope = this.currentThisScope();\n var inClassFieldInit = scope.inClassFieldInit;\n scope.inClassFieldInit = true;\n field.value = this.parseMaybeAssign();\n scope.inClassFieldInit = inClassFieldInit;\n } else {\n field.value = null;\n }\n this.semicolon();\n\n return this.finishNode(field, \"PropertyDefinition\")\n};\n\npp$8.parseClassStaticBlock = function(node) {\n node.body = [];\n\n var oldLabels = this.labels;\n this.labels = [];\n this.enterScope(SCOPE_CLASS_STATIC_BLOCK | SCOPE_SUPER);\n while (this.type !== types$1.braceR) {\n var stmt = this.parseStatement(null);\n node.body.push(stmt);\n }\n this.next();\n this.exitScope();\n this.labels = oldLabels;\n\n return this.finishNode(node, \"StaticBlock\")\n};\n\npp$8.parseClassId = function(node, isStatement) {\n if (this.type === types$1.name) {\n node.id = this.parseIdent();\n if (isStatement)\n { this.checkLValSimple(node.id, BIND_LEXICAL, false); }\n } else {\n if (isStatement === true)\n { this.unexpected(); }\n node.id = null;\n }\n};\n\npp$8.parseClassSuper = function(node) {\n node.superClass = this.eat(types$1._extends) ? this.parseExprSubscripts(null, false) : null;\n};\n\npp$8.enterClassBody = function() {\n var element = {declared: Object.create(null), used: []};\n this.privateNameStack.push(element);\n return element.declared\n};\n\npp$8.exitClassBody = function() {\n var ref = this.privateNameStack.pop();\n var declared = ref.declared;\n var used = ref.used;\n var len = this.privateNameStack.length;\n var parent = len === 0 ? null : this.privateNameStack[len - 1];\n for (var i = 0; i < used.length; ++i) {\n var id = used[i];\n if (!hasOwn(declared, id.name)) {\n if (parent) {\n parent.used.push(id);\n } else {\n this.raiseRecoverable(id.start, (\"Private field '#\" + (id.name) + \"' must be declared in an enclosing class\"));\n }\n }\n }\n};\n\nfunction isPrivateNameConflicted(privateNameMap, element) {\n var name = element.key.name;\n var curr = privateNameMap[name];\n\n var next = \"true\";\n if (element.type === \"MethodDefinition\" && (element.kind === \"get\" || element.kind === \"set\")) {\n next = (element.static ? \"s\" : \"i\") + element.kind;\n }\n\n // `class { get #a(){}; static set #a(_){} }` is also conflict.\n if (\n curr === \"iget\" && next === \"iset\" ||\n curr === \"iset\" && next === \"iget\" ||\n curr === \"sget\" && next === \"sset\" ||\n curr === \"sset\" && next === \"sget\"\n ) {\n privateNameMap[name] = \"true\";\n return false\n } else if (!curr) {\n privateNameMap[name] = next;\n return false\n } else {\n return true\n }\n}\n\nfunction checkKeyName(node, name) {\n var computed = node.computed;\n var key = node.key;\n return !computed && (\n key.type === \"Identifier\" && key.name === name ||\n key.type === \"Literal\" && key.value === name\n )\n}\n\n// Parses module export declaration.\n\npp$8.parseExport = function(node, exports) {\n this.next();\n // export * from '...'\n if (this.eat(types$1.star)) {\n if (this.options.ecmaVersion >= 11) {\n if (this.eatContextual(\"as\")) {\n node.exported = this.parseModuleExportName();\n this.checkExport(exports, node.exported, this.lastTokStart);\n } else {\n node.exported = null;\n }\n }\n this.expectContextual(\"from\");\n if (this.type !== types$1.string) { this.unexpected(); }\n node.source = this.parseExprAtom();\n this.semicolon();\n return this.finishNode(node, \"ExportAllDeclaration\")\n }\n if (this.eat(types$1._default)) { // export default ...\n this.checkExport(exports, \"default\", this.lastTokStart);\n var isAsync;\n if (this.type === types$1._function || (isAsync = this.isAsyncFunction())) {\n var fNode = this.startNode();\n this.next();\n if (isAsync) { this.next(); }\n node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync);\n } else if (this.type === types$1._class) {\n var cNode = this.startNode();\n node.declaration = this.parseClass(cNode, \"nullableID\");\n } else {\n node.declaration = this.parseMaybeAssign();\n this.semicolon();\n }\n return this.finishNode(node, \"ExportDefaultDeclaration\")\n }\n // export var|const|let|function|class ...\n if (this.shouldParseExportStatement()) {\n node.declaration = this.parseStatement(null);\n if (node.declaration.type === \"VariableDeclaration\")\n { this.checkVariableExport(exports, node.declaration.declarations); }\n else\n { this.checkExport(exports, node.declaration.id, node.declaration.id.start); }\n node.specifiers = [];\n node.source = null;\n } else { // export { x, y as z } [from '...']\n node.declaration = null;\n node.specifiers = this.parseExportSpecifiers(exports);\n if (this.eatContextual(\"from\")) {\n if (this.type !== types$1.string) { this.unexpected(); }\n node.source = this.parseExprAtom();\n } else {\n for (var i = 0, list = node.specifiers; i < list.length; i += 1) {\n // check for keywords used as local names\n var spec = list[i];\n\n this.checkUnreserved(spec.local);\n // check if export is defined\n this.checkLocalExport(spec.local);\n\n if (spec.local.type === \"Literal\") {\n this.raise(spec.local.start, \"A string literal cannot be used as an exported binding without `from`.\");\n }\n }\n\n node.source = null;\n }\n this.semicolon();\n }\n return this.finishNode(node, \"ExportNamedDeclaration\")\n};\n\npp$8.checkExport = function(exports, name, pos) {\n if (!exports) { return }\n if (typeof name !== \"string\")\n { name = name.type === \"Identifier\" ? name.name : name.value; }\n if (hasOwn(exports, name))\n { this.raiseRecoverable(pos, \"Duplicate export '\" + name + \"'\"); }\n exports[name] = true;\n};\n\npp$8.checkPatternExport = function(exports, pat) {\n var type = pat.type;\n if (type === \"Identifier\")\n { this.checkExport(exports, pat, pat.start); }\n else if (type === \"ObjectPattern\")\n { for (var i = 0, list = pat.properties; i < list.length; i += 1)\n {\n var prop = list[i];\n\n this.checkPatternExport(exports, prop);\n } }\n else if (type === \"ArrayPattern\")\n { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {\n var elt = list$1[i$1];\n\n if (elt) { this.checkPatternExport(exports, elt); }\n } }\n else if (type === \"Property\")\n { this.checkPatternExport(exports, pat.value); }\n else if (type === \"AssignmentPattern\")\n { this.checkPatternExport(exports, pat.left); }\n else if (type === \"RestElement\")\n { this.checkPatternExport(exports, pat.argument); }\n else if (type === \"ParenthesizedExpression\")\n { this.checkPatternExport(exports, pat.expression); }\n};\n\npp$8.checkVariableExport = function(exports, decls) {\n if (!exports) { return }\n for (var i = 0, list = decls; i < list.length; i += 1)\n {\n var decl = list[i];\n\n this.checkPatternExport(exports, decl.id);\n }\n};\n\npp$8.shouldParseExportStatement = function() {\n return this.type.keyword === \"var\" ||\n this.type.keyword === \"const\" ||\n this.type.keyword === \"class\" ||\n this.type.keyword === \"function\" ||\n this.isLet() ||\n this.isAsyncFunction()\n};\n\n// Parses a comma-separated list of module exports.\n\npp$8.parseExportSpecifiers = function(exports) {\n var nodes = [], first = true;\n // export { x, y as z } [from '...']\n this.expect(types$1.braceL);\n while (!this.eat(types$1.braceR)) {\n if (!first) {\n this.expect(types$1.comma);\n if (this.afterTrailingComma(types$1.braceR)) { break }\n } else { first = false; }\n\n var node = this.startNode();\n node.local = this.parseModuleExportName();\n node.exported = this.eatContextual(\"as\") ? this.parseModuleExportName() : node.local;\n this.checkExport(\n exports,\n node.exported,\n node.exported.start\n );\n nodes.push(this.finishNode(node, \"ExportSpecifier\"));\n }\n return nodes\n};\n\n// Parses import declaration.\n\npp$8.parseImport = function(node) {\n this.next();\n // import '...'\n if (this.type === types$1.string) {\n node.specifiers = empty$1;\n node.source = this.parseExprAtom();\n } else {\n node.specifiers = this.parseImportSpecifiers();\n this.expectContextual(\"from\");\n node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected();\n }\n this.semicolon();\n return this.finishNode(node, \"ImportDeclaration\")\n};\n\n// Parses a comma-separated list of module imports.\n\npp$8.parseImportSpecifiers = function() {\n var nodes = [], first = true;\n if (this.type === types$1.name) {\n // import defaultObj, { x, y as z } from '...'\n var node = this.startNode();\n node.local = this.parseIdent();\n this.checkLValSimple(node.local, BIND_LEXICAL);\n nodes.push(this.finishNode(node, \"ImportDefaultSpecifier\"));\n if (!this.eat(types$1.comma)) { return nodes }\n }\n if (this.type === types$1.star) {\n var node$1 = this.startNode();\n this.next();\n this.expectContextual(\"as\");\n node$1.local = this.parseIdent();\n this.checkLValSimple(node$1.local, BIND_LEXICAL);\n nodes.push(this.finishNode(node$1, \"ImportNamespaceSpecifier\"));\n return nodes\n }\n this.expect(types$1.braceL);\n while (!this.eat(types$1.braceR)) {\n if (!first) {\n this.expect(types$1.comma);\n if (this.afterTrailingComma(types$1.braceR)) { break }\n } else { first = false; }\n\n var node$2 = this.startNode();\n node$2.imported = this.parseModuleExportName();\n if (this.eatContextual(\"as\")) {\n node$2.local = this.parseIdent();\n } else {\n this.checkUnreserved(node$2.imported);\n node$2.local = node$2.imported;\n }\n this.checkLValSimple(node$2.local, BIND_LEXICAL);\n nodes.push(this.finishNode(node$2, \"ImportSpecifier\"));\n }\n return nodes\n};\n\npp$8.parseModuleExportName = function() {\n if (this.options.ecmaVersion >= 13 && this.type === types$1.string) {\n var stringLiteral = this.parseLiteral(this.value);\n if (loneSurrogate.test(stringLiteral.value)) {\n this.raise(stringLiteral.start, \"An export name cannot include a lone surrogate.\");\n }\n return stringLiteral\n }\n return this.parseIdent(true)\n};\n\n// Set `ExpressionStatement#directive` property for directive prologues.\npp$8.adaptDirectivePrologue = function(statements) {\n for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {\n statements[i].directive = statements[i].expression.raw.slice(1, -1);\n }\n};\npp$8.isDirectiveCandidate = function(statement) {\n return (\n this.options.ecmaVersion >= 5 &&\n statement.type === \"ExpressionStatement\" &&\n statement.expression.type === \"Literal\" &&\n typeof statement.expression.value === \"string\" &&\n // Reject parenthesized strings.\n (this.input[statement.start] === \"\\\"\" || this.input[statement.start] === \"'\")\n )\n};\n\nvar pp$7 = Parser.prototype;\n\n// Convert existing expression atom to assignable pattern\n// if possible.\n\npp$7.toAssignable = function(node, isBinding, refDestructuringErrors) {\n if (this.options.ecmaVersion >= 6 && node) {\n switch (node.type) {\n case \"Identifier\":\n if (this.inAsync && node.name === \"await\")\n { this.raise(node.start, \"Cannot use 'await' as identifier inside an async function\"); }\n break\n\n case \"ObjectPattern\":\n case \"ArrayPattern\":\n case \"AssignmentPattern\":\n case \"RestElement\":\n break\n\n case \"ObjectExpression\":\n node.type = \"ObjectPattern\";\n if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n for (var i = 0, list = node.properties; i < list.length; i += 1) {\n var prop = list[i];\n\n this.toAssignable(prop, isBinding);\n // Early error:\n // AssignmentRestProperty[Yield, Await] :\n // `...` DestructuringAssignmentTarget[Yield, Await]\n //\n // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.\n if (\n prop.type === \"RestElement\" &&\n (prop.argument.type === \"ArrayPattern\" || prop.argument.type === \"ObjectPattern\")\n ) {\n this.raise(prop.argument.start, \"Unexpected token\");\n }\n }\n break\n\n case \"Property\":\n // AssignmentProperty has type === \"Property\"\n if (node.kind !== \"init\") { this.raise(node.key.start, \"Object pattern can't contain getter or setter\"); }\n this.toAssignable(node.value, isBinding);\n break\n\n case \"ArrayExpression\":\n node.type = \"ArrayPattern\";\n if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n this.toAssignableList(node.elements, isBinding);\n break\n\n case \"SpreadElement\":\n node.type = \"RestElement\";\n this.toAssignable(node.argument, isBinding);\n if (node.argument.type === \"AssignmentPattern\")\n { this.raise(node.argument.start, \"Rest elements cannot have a default value\"); }\n break\n\n case \"AssignmentExpression\":\n if (node.operator !== \"=\") { this.raise(node.left.end, \"Only '=' operator can be used for specifying default value.\"); }\n node.type = \"AssignmentPattern\";\n delete node.operator;\n this.toAssignable(node.left, isBinding);\n break\n\n case \"ParenthesizedExpression\":\n this.toAssignable(node.expression, isBinding, refDestructuringErrors);\n break\n\n case \"ChainExpression\":\n this.raiseRecoverable(node.start, \"Optional chaining cannot appear in left-hand side\");\n break\n\n case \"MemberExpression\":\n if (!isBinding) { break }\n\n default:\n this.raise(node.start, \"Assigning to rvalue\");\n }\n } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n return node\n};\n\n// Convert list of expression atoms to binding list.\n\npp$7.toAssignableList = function(exprList, isBinding) {\n var end = exprList.length;\n for (var i = 0; i < end; i++) {\n var elt = exprList[i];\n if (elt) { this.toAssignable(elt, isBinding); }\n }\n if (end) {\n var last = exprList[end - 1];\n if (this.options.ecmaVersion === 6 && isBinding && last && last.type === \"RestElement\" && last.argument.type !== \"Identifier\")\n { this.unexpected(last.argument.start); }\n }\n return exprList\n};\n\n// Parses spread element.\n\npp$7.parseSpread = function(refDestructuringErrors) {\n var node = this.startNode();\n this.next();\n node.argument = this.parseMaybeAssign(false, refDestructuringErrors);\n return this.finishNode(node, \"SpreadElement\")\n};\n\npp$7.parseRestBinding = function() {\n var node = this.startNode();\n this.next();\n\n // RestElement inside of a function parameter must be an identifier\n if (this.options.ecmaVersion === 6 && this.type !== types$1.name)\n { this.unexpected(); }\n\n node.argument = this.parseBindingAtom();\n\n return this.finishNode(node, \"RestElement\")\n};\n\n// Parses lvalue (assignable) atom.\n\npp$7.parseBindingAtom = function() {\n if (this.options.ecmaVersion >= 6) {\n switch (this.type) {\n case types$1.bracketL:\n var node = this.startNode();\n this.next();\n node.elements = this.parseBindingList(types$1.bracketR, true, true);\n return this.finishNode(node, \"ArrayPattern\")\n\n case types$1.braceL:\n return this.parseObj(true)\n }\n }\n return this.parseIdent()\n};\n\npp$7.parseBindingList = function(close, allowEmpty, allowTrailingComma) {\n var elts = [], first = true;\n while (!this.eat(close)) {\n if (first) { first = false; }\n else { this.expect(types$1.comma); }\n if (allowEmpty && this.type === types$1.comma) {\n elts.push(null);\n } else if (allowTrailingComma && this.afterTrailingComma(close)) {\n break\n } else if (this.type === types$1.ellipsis) {\n var rest = this.parseRestBinding();\n this.parseBindingListItem(rest);\n elts.push(rest);\n if (this.type === types$1.comma) { this.raise(this.start, \"Comma is not permitted after the rest element\"); }\n this.expect(close);\n break\n } else {\n var elem = this.parseMaybeDefault(this.start, this.startLoc);\n this.parseBindingListItem(elem);\n elts.push(elem);\n }\n }\n return elts\n};\n\npp$7.parseBindingListItem = function(param) {\n return param\n};\n\n// Parses assignment pattern around given atom if possible.\n\npp$7.parseMaybeDefault = function(startPos, startLoc, left) {\n left = left || this.parseBindingAtom();\n if (this.options.ecmaVersion < 6 || !this.eat(types$1.eq)) { return left }\n var node = this.startNodeAt(startPos, startLoc);\n node.left = left;\n node.right = this.parseMaybeAssign();\n return this.finishNode(node, \"AssignmentPattern\")\n};\n\n// The following three functions all verify that a node is an lvalue —\n// something that can be bound, or assigned to. In order to do so, they perform\n// a variety of checks:\n//\n// - Check that none of the bound/assigned-to identifiers are reserved words.\n// - Record name declarations for bindings in the appropriate scope.\n// - Check duplicate argument names, if checkClashes is set.\n//\n// If a complex binding pattern is encountered (e.g., object and array\n// destructuring), the entire pattern is recursively checked.\n//\n// There are three versions of checkLVal*() appropriate for different\n// circumstances:\n//\n// - checkLValSimple() shall be used if the syntactic construct supports\n// nothing other than identifiers and member expressions. Parenthesized\n// expressions are also correctly handled. This is generally appropriate for\n// constructs for which the spec says\n//\n// > It is a Syntax Error if AssignmentTargetType of [the production] is not\n// > simple.\n//\n// It is also appropriate for checking if an identifier is valid and not\n// defined elsewhere, like import declarations or function/class identifiers.\n//\n// Examples where this is used include:\n// a += …;\n// import a from '…';\n// where a is the node to be checked.\n//\n// - checkLValPattern() shall be used if the syntactic construct supports\n// anything checkLValSimple() supports, as well as object and array\n// destructuring patterns. This is generally appropriate for constructs for\n// which the spec says\n//\n// > It is a Syntax Error if [the production] is neither an ObjectLiteral nor\n// > an ArrayLiteral and AssignmentTargetType of [the production] is not\n// > simple.\n//\n// Examples where this is used include:\n// (a = …);\n// const a = …;\n// try { … } catch (a) { … }\n// where a is the node to be checked.\n//\n// - checkLValInnerPattern() shall be used if the syntactic construct supports\n// anything checkLValPattern() supports, as well as default assignment\n// patterns, rest elements, and other constructs that may appear within an\n// object or array destructuring pattern.\n//\n// As a special case, function parameters also use checkLValInnerPattern(),\n// as they also support defaults and rest constructs.\n//\n// These functions deliberately support both assignment and binding constructs,\n// as the logic for both is exceedingly similar. If the node is the target of\n// an assignment, then bindingType should be set to BIND_NONE. Otherwise, it\n// should be set to the appropriate BIND_* constant, like BIND_VAR or\n// BIND_LEXICAL.\n//\n// If the function is called with a non-BIND_NONE bindingType, then\n// additionally a checkClashes object may be specified to allow checking for\n// duplicate argument names. checkClashes is ignored if the provided construct\n// is an assignment (i.e., bindingType is BIND_NONE).\n\npp$7.checkLValSimple = function(expr, bindingType, checkClashes) {\n if ( bindingType === void 0 ) bindingType = BIND_NONE;\n\n var isBind = bindingType !== BIND_NONE;\n\n switch (expr.type) {\n case \"Identifier\":\n if (this.strict && this.reservedWordsStrictBind.test(expr.name))\n { this.raiseRecoverable(expr.start, (isBind ? \"Binding \" : \"Assigning to \") + expr.name + \" in strict mode\"); }\n if (isBind) {\n if (bindingType === BIND_LEXICAL && expr.name === \"let\")\n { this.raiseRecoverable(expr.start, \"let is disallowed as a lexically bound name\"); }\n if (checkClashes) {\n if (hasOwn(checkClashes, expr.name))\n { this.raiseRecoverable(expr.start, \"Argument name clash\"); }\n checkClashes[expr.name] = true;\n }\n if (bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); }\n }\n break\n\n case \"ChainExpression\":\n this.raiseRecoverable(expr.start, \"Optional chaining cannot appear in left-hand side\");\n break\n\n case \"MemberExpression\":\n if (isBind) { this.raiseRecoverable(expr.start, \"Binding member expression\"); }\n break\n\n case \"ParenthesizedExpression\":\n if (isBind) { this.raiseRecoverable(expr.start, \"Binding parenthesized expression\"); }\n return this.checkLValSimple(expr.expression, bindingType, checkClashes)\n\n default:\n this.raise(expr.start, (isBind ? \"Binding\" : \"Assigning to\") + \" rvalue\");\n }\n};\n\npp$7.checkLValPattern = function(expr, bindingType, checkClashes) {\n if ( bindingType === void 0 ) bindingType = BIND_NONE;\n\n switch (expr.type) {\n case \"ObjectPattern\":\n for (var i = 0, list = expr.properties; i < list.length; i += 1) {\n var prop = list[i];\n\n this.checkLValInnerPattern(prop, bindingType, checkClashes);\n }\n break\n\n case \"ArrayPattern\":\n for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {\n var elem = list$1[i$1];\n\n if (elem) { this.checkLValInnerPattern(elem, bindingType, checkClashes); }\n }\n break\n\n default:\n this.checkLValSimple(expr, bindingType, checkClashes);\n }\n};\n\npp$7.checkLValInnerPattern = function(expr, bindingType, checkClashes) {\n if ( bindingType === void 0 ) bindingType = BIND_NONE;\n\n switch (expr.type) {\n case \"Property\":\n // AssignmentProperty has type === \"Property\"\n this.checkLValInnerPattern(expr.value, bindingType, checkClashes);\n break\n\n case \"AssignmentPattern\":\n this.checkLValPattern(expr.left, bindingType, checkClashes);\n break\n\n case \"RestElement\":\n this.checkLValPattern(expr.argument, bindingType, checkClashes);\n break\n\n default:\n this.checkLValPattern(expr, bindingType, checkClashes);\n }\n};\n\n// The algorithm used to determine whether a regexp can appear at a\n\nvar TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {\n this.token = token;\n this.isExpr = !!isExpr;\n this.preserveSpace = !!preserveSpace;\n this.override = override;\n this.generator = !!generator;\n};\n\nvar types = {\n b_stat: new TokContext(\"{\", false),\n b_expr: new TokContext(\"{\", true),\n b_tmpl: new TokContext(\"${\", false),\n p_stat: new TokContext(\"(\", false),\n p_expr: new TokContext(\"(\", true),\n q_tmpl: new TokContext(\"`\", true, true, function (p) { return p.tryReadTemplateToken(); }),\n f_stat: new TokContext(\"function\", false),\n f_expr: new TokContext(\"function\", true),\n f_expr_gen: new TokContext(\"function\", true, false, null, true),\n f_gen: new TokContext(\"function\", false, false, null, true)\n};\n\nvar pp$6 = Parser.prototype;\n\npp$6.initialContext = function() {\n return [types.b_stat]\n};\n\npp$6.curContext = function() {\n return this.context[this.context.length - 1]\n};\n\npp$6.braceIsBlock = function(prevType) {\n var parent = this.curContext();\n if (parent === types.f_expr || parent === types.f_stat)\n { return true }\n if (prevType === types$1.colon && (parent === types.b_stat || parent === types.b_expr))\n { return !parent.isExpr }\n\n // The check for `tt.name && exprAllowed` detects whether we are\n // after a `yield` or `of` construct. See the `updateContext` for\n // `tt.name`.\n if (prevType === types$1._return || prevType === types$1.name && this.exprAllowed)\n { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }\n if (prevType === types$1._else || prevType === types$1.semi || prevType === types$1.eof || prevType === types$1.parenR || prevType === types$1.arrow)\n { return true }\n if (prevType === types$1.braceL)\n { return parent === types.b_stat }\n if (prevType === types$1._var || prevType === types$1._const || prevType === types$1.name)\n { return false }\n return !this.exprAllowed\n};\n\npp$6.inGeneratorContext = function() {\n for (var i = this.context.length - 1; i >= 1; i--) {\n var context = this.context[i];\n if (context.token === \"function\")\n { return context.generator }\n }\n return false\n};\n\npp$6.updateContext = function(prevType) {\n var update, type = this.type;\n if (type.keyword && prevType === types$1.dot)\n { this.exprAllowed = false; }\n else if (update = type.updateContext)\n { update.call(this, prevType); }\n else\n { this.exprAllowed = type.beforeExpr; }\n};\n\n// Used to handle egde cases when token context could not be inferred correctly during tokenization phase\n\npp$6.overrideContext = function(tokenCtx) {\n if (this.curContext() !== tokenCtx) {\n this.context[this.context.length - 1] = tokenCtx;\n }\n};\n\n// Token-specific context update code\n\ntypes$1.parenR.updateContext = types$1.braceR.updateContext = function() {\n if (this.context.length === 1) {\n this.exprAllowed = true;\n return\n }\n var out = this.context.pop();\n if (out === types.b_stat && this.curContext().token === \"function\") {\n out = this.context.pop();\n }\n this.exprAllowed = !out.isExpr;\n};\n\ntypes$1.braceL.updateContext = function(prevType) {\n this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr);\n this.exprAllowed = true;\n};\n\ntypes$1.dollarBraceL.updateContext = function() {\n this.context.push(types.b_tmpl);\n this.exprAllowed = true;\n};\n\ntypes$1.parenL.updateContext = function(prevType) {\n var statementParens = prevType === types$1._if || prevType === types$1._for || prevType === types$1._with || prevType === types$1._while;\n this.context.push(statementParens ? types.p_stat : types.p_expr);\n this.exprAllowed = true;\n};\n\ntypes$1.incDec.updateContext = function() {\n // tokExprAllowed stays unchanged\n};\n\ntypes$1._function.updateContext = types$1._class.updateContext = function(prevType) {\n if (prevType.beforeExpr && prevType !== types$1._else &&\n !(prevType === types$1.semi && this.curContext() !== types.p_stat) &&\n !(prevType === types$1._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) &&\n !((prevType === types$1.colon || prevType === types$1.braceL) && this.curContext() === types.b_stat))\n { this.context.push(types.f_expr); }\n else\n { this.context.push(types.f_stat); }\n this.exprAllowed = false;\n};\n\ntypes$1.backQuote.updateContext = function() {\n if (this.curContext() === types.q_tmpl)\n { this.context.pop(); }\n else\n { this.context.push(types.q_tmpl); }\n this.exprAllowed = false;\n};\n\ntypes$1.star.updateContext = function(prevType) {\n if (prevType === types$1._function) {\n var index = this.context.length - 1;\n if (this.context[index] === types.f_expr)\n { this.context[index] = types.f_expr_gen; }\n else\n { this.context[index] = types.f_gen; }\n }\n this.exprAllowed = true;\n};\n\ntypes$1.name.updateContext = function(prevType) {\n var allowed = false;\n if (this.options.ecmaVersion >= 6 && prevType !== types$1.dot) {\n if (this.value === \"of\" && !this.exprAllowed ||\n this.value === \"yield\" && this.inGeneratorContext())\n { allowed = true; }\n }\n this.exprAllowed = allowed;\n};\n\n// A recursive descent parser operates by defining functions for all\n\nvar pp$5 = Parser.prototype;\n\n// Check if property name clashes with already added.\n// Object/class getters and setters are not allowed to clash —\n// either with each other or with an init property — and in\n// strict mode, init properties are also not allowed to be repeated.\n\npp$5.checkPropClash = function(prop, propHash, refDestructuringErrors) {\n if (this.options.ecmaVersion >= 9 && prop.type === \"SpreadElement\")\n { return }\n if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))\n { return }\n var key = prop.key;\n var name;\n switch (key.type) {\n case \"Identifier\": name = key.name; break\n case \"Literal\": name = String(key.value); break\n default: return\n }\n var kind = prop.kind;\n if (this.options.ecmaVersion >= 6) {\n if (name === \"__proto__\" && kind === \"init\") {\n if (propHash.proto) {\n if (refDestructuringErrors) {\n if (refDestructuringErrors.doubleProto < 0) {\n refDestructuringErrors.doubleProto = key.start;\n }\n } else {\n this.raiseRecoverable(key.start, \"Redefinition of __proto__ property\");\n }\n }\n propHash.proto = true;\n }\n return\n }\n name = \"$\" + name;\n var other = propHash[name];\n if (other) {\n var redefinition;\n if (kind === \"init\") {\n redefinition = this.strict && other.init || other.get || other.set;\n } else {\n redefinition = other.init || other[kind];\n }\n if (redefinition)\n { this.raiseRecoverable(key.start, \"Redefinition of property\"); }\n } else {\n other = propHash[name] = {\n init: false,\n get: false,\n set: false\n };\n }\n other[kind] = true;\n};\n\n// ### Expression parsing\n\n// These nest, from the most general expression type at the top to\n// 'atomic', nondivisible expression types at the bottom. Most of\n// the functions will simply let the function(s) below them parse,\n// and, *if* the syntactic construct they handle is present, wrap\n// the AST node that the inner parser gave them in another node.\n\n// Parse a full expression. The optional arguments are used to\n// forbid the `in` operator (in for loops initalization expressions)\n// and provide reference for storing '=' operator inside shorthand\n// property assignment in contexts where both object expression\n// and object pattern might appear (so it's possible to raise\n// delayed syntax error at correct position).\n\npp$5.parseExpression = function(forInit, refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseMaybeAssign(forInit, refDestructuringErrors);\n if (this.type === types$1.comma) {\n var node = this.startNodeAt(startPos, startLoc);\n node.expressions = [expr];\n while (this.eat(types$1.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); }\n return this.finishNode(node, \"SequenceExpression\")\n }\n return expr\n};\n\n// Parse an assignment expression. This includes applications of\n// operators like `+=`.\n\npp$5.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) {\n if (this.isContextual(\"yield\")) {\n if (this.inGenerator) { return this.parseYield(forInit) }\n // The tokenizer will assume an expression is allowed after\n // `yield`, but this isn't that kind of yield\n else { this.exprAllowed = false; }\n }\n\n var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldDoubleProto = -1;\n if (refDestructuringErrors) {\n oldParenAssign = refDestructuringErrors.parenthesizedAssign;\n oldTrailingComma = refDestructuringErrors.trailingComma;\n oldDoubleProto = refDestructuringErrors.doubleProto;\n refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;\n } else {\n refDestructuringErrors = new DestructuringErrors;\n ownDestructuringErrors = true;\n }\n\n var startPos = this.start, startLoc = this.startLoc;\n if (this.type === types$1.parenL || this.type === types$1.name) {\n this.potentialArrowAt = this.start;\n this.potentialArrowInForAwait = forInit === \"await\";\n }\n var left = this.parseMaybeConditional(forInit, refDestructuringErrors);\n if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }\n if (this.type.isAssign) {\n var node = this.startNodeAt(startPos, startLoc);\n node.operator = this.value;\n if (this.type === types$1.eq)\n { left = this.toAssignable(left, false, refDestructuringErrors); }\n if (!ownDestructuringErrors) {\n refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1;\n }\n if (refDestructuringErrors.shorthandAssign >= left.start)\n { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly\n if (this.type === types$1.eq)\n { this.checkLValPattern(left); }\n else\n { this.checkLValSimple(left); }\n node.left = left;\n this.next();\n node.right = this.parseMaybeAssign(forInit);\n if (oldDoubleProto > -1) { refDestructuringErrors.doubleProto = oldDoubleProto; }\n return this.finishNode(node, \"AssignmentExpression\")\n } else {\n if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }\n }\n if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }\n if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }\n return left\n};\n\n// Parse a ternary conditional (`?:`) operator.\n\npp$5.parseMaybeConditional = function(forInit, refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseExprOps(forInit, refDestructuringErrors);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n if (this.eat(types$1.question)) {\n var node = this.startNodeAt(startPos, startLoc);\n node.test = expr;\n node.consequent = this.parseMaybeAssign();\n this.expect(types$1.colon);\n node.alternate = this.parseMaybeAssign(forInit);\n return this.finishNode(node, \"ConditionalExpression\")\n }\n return expr\n};\n\n// Start the precedence parser.\n\npp$5.parseExprOps = function(forInit, refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseMaybeUnary(refDestructuringErrors, false, false, forInit);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n return expr.start === startPos && expr.type === \"ArrowFunctionExpression\" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit)\n};\n\n// Parse binary operators with the operator precedence parsing\n// algorithm. `left` is the left-hand side of the operator.\n// `minPrec` provides context that allows the function to stop and\n// defer further parser to one of its callers when it encounters an\n// operator that has a lower precedence than the set it is parsing.\n\npp$5.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) {\n var prec = this.type.binop;\n if (prec != null && (!forInit || this.type !== types$1._in)) {\n if (prec > minPrec) {\n var logical = this.type === types$1.logicalOR || this.type === types$1.logicalAND;\n var coalesce = this.type === types$1.coalesce;\n if (coalesce) {\n // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions.\n // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error.\n prec = types$1.logicalAND.binop;\n }\n var op = this.value;\n this.next();\n var startPos = this.start, startLoc = this.startLoc;\n var right = this.parseExprOp(this.parseMaybeUnary(null, false, false, forInit), startPos, startLoc, prec, forInit);\n var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce);\n if ((logical && this.type === types$1.coalesce) || (coalesce && (this.type === types$1.logicalOR || this.type === types$1.logicalAND))) {\n this.raiseRecoverable(this.start, \"Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses\");\n }\n return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit)\n }\n }\n return left\n};\n\npp$5.buildBinary = function(startPos, startLoc, left, right, op, logical) {\n if (right.type === \"PrivateIdentifier\") { this.raise(right.start, \"Private identifier can only be left side of binary expression\"); }\n var node = this.startNodeAt(startPos, startLoc);\n node.left = left;\n node.operator = op;\n node.right = right;\n return this.finishNode(node, logical ? \"LogicalExpression\" : \"BinaryExpression\")\n};\n\n// Parse unary operators, both prefix and postfix.\n\npp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forInit) {\n var startPos = this.start, startLoc = this.startLoc, expr;\n if (this.isContextual(\"await\") && this.canAwait) {\n expr = this.parseAwait(forInit);\n sawUnary = true;\n } else if (this.type.prefix) {\n var node = this.startNode(), update = this.type === types$1.incDec;\n node.operator = this.value;\n node.prefix = true;\n this.next();\n node.argument = this.parseMaybeUnary(null, true, update, forInit);\n this.checkExpressionErrors(refDestructuringErrors, true);\n if (update) { this.checkLValSimple(node.argument); }\n else if (this.strict && node.operator === \"delete\" &&\n node.argument.type === \"Identifier\")\n { this.raiseRecoverable(node.start, \"Deleting local variable in strict mode\"); }\n else if (node.operator === \"delete\" && isPrivateFieldAccess(node.argument))\n { this.raiseRecoverable(node.start, \"Private fields can not be deleted\"); }\n else { sawUnary = true; }\n expr = this.finishNode(node, update ? \"UpdateExpression\" : \"UnaryExpression\");\n } else if (!sawUnary && this.type === types$1.privateId) {\n if (forInit || this.privateNameStack.length === 0) { this.unexpected(); }\n expr = this.parsePrivateIdent();\n // only could be private fields in 'in', such as #x in obj\n if (this.type !== types$1._in) { this.unexpected(); }\n } else {\n expr = this.parseExprSubscripts(refDestructuringErrors, forInit);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n while (this.type.postfix && !this.canInsertSemicolon()) {\n var node$1 = this.startNodeAt(startPos, startLoc);\n node$1.operator = this.value;\n node$1.prefix = false;\n node$1.argument = expr;\n this.checkLValSimple(expr);\n this.next();\n expr = this.finishNode(node$1, \"UpdateExpression\");\n }\n }\n\n if (!incDec && this.eat(types$1.starstar)) {\n if (sawUnary)\n { this.unexpected(this.lastTokStart); }\n else\n { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false, false, forInit), \"**\", false) }\n } else {\n return expr\n }\n};\n\nfunction isPrivateFieldAccess(node) {\n return (\n node.type === \"MemberExpression\" && node.property.type === \"PrivateIdentifier\" ||\n node.type === \"ChainExpression\" && isPrivateFieldAccess(node.expression)\n )\n}\n\n// Parse call, dot, and `[]`-subscript expressions.\n\npp$5.parseExprSubscripts = function(refDestructuringErrors, forInit) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseExprAtom(refDestructuringErrors, forInit);\n if (expr.type === \"ArrowFunctionExpression\" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== \")\")\n { return expr }\n var result = this.parseSubscripts(expr, startPos, startLoc, false, forInit);\n if (refDestructuringErrors && result.type === \"MemberExpression\") {\n if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }\n if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }\n if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; }\n }\n return result\n};\n\npp$5.parseSubscripts = function(base, startPos, startLoc, noCalls, forInit) {\n var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === \"Identifier\" && base.name === \"async\" &&\n this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 &&\n this.potentialArrowAt === base.start;\n var optionalChained = false;\n\n while (true) {\n var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit);\n\n if (element.optional) { optionalChained = true; }\n if (element === base || element.type === \"ArrowFunctionExpression\") {\n if (optionalChained) {\n var chainNode = this.startNodeAt(startPos, startLoc);\n chainNode.expression = element;\n element = this.finishNode(chainNode, \"ChainExpression\");\n }\n return element\n }\n\n base = element;\n }\n};\n\npp$5.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) {\n var optionalSupported = this.options.ecmaVersion >= 11;\n var optional = optionalSupported && this.eat(types$1.questionDot);\n if (noCalls && optional) { this.raise(this.lastTokStart, \"Optional chaining cannot appear in the callee of new expressions\"); }\n\n var computed = this.eat(types$1.bracketL);\n if (computed || (optional && this.type !== types$1.parenL && this.type !== types$1.backQuote) || this.eat(types$1.dot)) {\n var node = this.startNodeAt(startPos, startLoc);\n node.object = base;\n if (computed) {\n node.property = this.parseExpression();\n this.expect(types$1.bracketR);\n } else if (this.type === types$1.privateId && base.type !== \"Super\") {\n node.property = this.parsePrivateIdent();\n } else {\n node.property = this.parseIdent(this.options.allowReserved !== \"never\");\n }\n node.computed = !!computed;\n if (optionalSupported) {\n node.optional = optional;\n }\n base = this.finishNode(node, \"MemberExpression\");\n } else if (!noCalls && this.eat(types$1.parenL)) {\n var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.awaitIdentPos = 0;\n var exprList = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors);\n if (maybeAsyncArrow && !optional && !this.canInsertSemicolon() && this.eat(types$1.arrow)) {\n this.checkPatternErrors(refDestructuringErrors, false);\n this.checkYieldAwaitInDefaultParams();\n if (this.awaitIdentPos > 0)\n { this.raise(this.awaitIdentPos, \"Cannot use 'await' as identifier inside an async function\"); }\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.awaitIdentPos = oldAwaitIdentPos;\n return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true, forInit)\n }\n this.checkExpressionErrors(refDestructuringErrors, true);\n this.yieldPos = oldYieldPos || this.yieldPos;\n this.awaitPos = oldAwaitPos || this.awaitPos;\n this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos;\n var node$1 = this.startNodeAt(startPos, startLoc);\n node$1.callee = base;\n node$1.arguments = exprList;\n if (optionalSupported) {\n node$1.optional = optional;\n }\n base = this.finishNode(node$1, \"CallExpression\");\n } else if (this.type === types$1.backQuote) {\n if (optional || optionalChained) {\n this.raise(this.start, \"Optional chaining cannot appear in the tag of tagged template expressions\");\n }\n var node$2 = this.startNodeAt(startPos, startLoc);\n node$2.tag = base;\n node$2.quasi = this.parseTemplate({isTagged: true});\n base = this.finishNode(node$2, \"TaggedTemplateExpression\");\n }\n return base\n};\n\n// Parse an atomic expression — either a single token that is an\n// expression, an expression started by a keyword like `function` or\n// `new`, or an expression wrapped in punctuation like `()`, `[]`,\n// or `{}`.\n\npp$5.parseExprAtom = function(refDestructuringErrors, forInit) {\n // If a division operator appears in an expression position, the\n // tokenizer got confused, and we force it to read a regexp instead.\n if (this.type === types$1.slash) { this.readRegexp(); }\n\n var node, canBeArrow = this.potentialArrowAt === this.start;\n switch (this.type) {\n case types$1._super:\n if (!this.allowSuper)\n { this.raise(this.start, \"'super' keyword outside a method\"); }\n node = this.startNode();\n this.next();\n if (this.type === types$1.parenL && !this.allowDirectSuper)\n { this.raise(node.start, \"super() call outside constructor of a subclass\"); }\n // The `super` keyword can appear at below:\n // SuperProperty:\n // super [ Expression ]\n // super . IdentifierName\n // SuperCall:\n // super ( Arguments )\n if (this.type !== types$1.dot && this.type !== types$1.bracketL && this.type !== types$1.parenL)\n { this.unexpected(); }\n return this.finishNode(node, \"Super\")\n\n case types$1._this:\n node = this.startNode();\n this.next();\n return this.finishNode(node, \"ThisExpression\")\n\n case types$1.name:\n var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;\n var id = this.parseIdent(false);\n if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === \"async\" && !this.canInsertSemicolon() && this.eat(types$1._function)) {\n this.overrideContext(types.f_expr);\n return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true, forInit)\n }\n if (canBeArrow && !this.canInsertSemicolon()) {\n if (this.eat(types$1.arrow))\n { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false, forInit) }\n if (this.options.ecmaVersion >= 8 && id.name === \"async\" && this.type === types$1.name && !containsEsc &&\n (!this.potentialArrowInForAwait || this.value !== \"of\" || this.containsEsc)) {\n id = this.parseIdent(false);\n if (this.canInsertSemicolon() || !this.eat(types$1.arrow))\n { this.unexpected(); }\n return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true, forInit)\n }\n }\n return id\n\n case types$1.regexp:\n var value = this.value;\n node = this.parseLiteral(value.value);\n node.regex = {pattern: value.pattern, flags: value.flags};\n return node\n\n case types$1.num: case types$1.string:\n return this.parseLiteral(this.value)\n\n case types$1._null: case types$1._true: case types$1._false:\n node = this.startNode();\n node.value = this.type === types$1._null ? null : this.type === types$1._true;\n node.raw = this.type.keyword;\n this.next();\n return this.finishNode(node, \"Literal\")\n\n case types$1.parenL:\n var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow, forInit);\n if (refDestructuringErrors) {\n if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))\n { refDestructuringErrors.parenthesizedAssign = start; }\n if (refDestructuringErrors.parenthesizedBind < 0)\n { refDestructuringErrors.parenthesizedBind = start; }\n }\n return expr\n\n case types$1.bracketL:\n node = this.startNode();\n this.next();\n node.elements = this.parseExprList(types$1.bracketR, true, true, refDestructuringErrors);\n return this.finishNode(node, \"ArrayExpression\")\n\n case types$1.braceL:\n this.overrideContext(types.b_expr);\n return this.parseObj(false, refDestructuringErrors)\n\n case types$1._function:\n node = this.startNode();\n this.next();\n return this.parseFunction(node, 0)\n\n case types$1._class:\n return this.parseClass(this.startNode(), false)\n\n case types$1._new:\n return this.parseNew()\n\n case types$1.backQuote:\n return this.parseTemplate()\n\n case types$1._import:\n if (this.options.ecmaVersion >= 11) {\n return this.parseExprImport()\n } else {\n return this.unexpected()\n }\n\n default:\n this.unexpected();\n }\n};\n\npp$5.parseExprImport = function() {\n var node = this.startNode();\n\n // Consume `import` as an identifier for `import.meta`.\n // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`.\n if (this.containsEsc) { this.raiseRecoverable(this.start, \"Escape sequence in keyword import\"); }\n var meta = this.parseIdent(true);\n\n switch (this.type) {\n case types$1.parenL:\n return this.parseDynamicImport(node)\n case types$1.dot:\n node.meta = meta;\n return this.parseImportMeta(node)\n default:\n this.unexpected();\n }\n};\n\npp$5.parseDynamicImport = function(node) {\n this.next(); // skip `(`\n\n // Parse node.source.\n node.source = this.parseMaybeAssign();\n\n // Verify ending.\n if (!this.eat(types$1.parenR)) {\n var errorPos = this.start;\n if (this.eat(types$1.comma) && this.eat(types$1.parenR)) {\n this.raiseRecoverable(errorPos, \"Trailing comma is not allowed in import()\");\n } else {\n this.unexpected(errorPos);\n }\n }\n\n return this.finishNode(node, \"ImportExpression\")\n};\n\npp$5.parseImportMeta = function(node) {\n this.next(); // skip `.`\n\n var containsEsc = this.containsEsc;\n node.property = this.parseIdent(true);\n\n if (node.property.name !== \"meta\")\n { this.raiseRecoverable(node.property.start, \"The only valid meta property for import is 'import.meta'\"); }\n if (containsEsc)\n { this.raiseRecoverable(node.start, \"'import.meta' must not contain escaped characters\"); }\n if (this.options.sourceType !== \"module\" && !this.options.allowImportExportEverywhere)\n { this.raiseRecoverable(node.start, \"Cannot use 'import.meta' outside a module\"); }\n\n return this.finishNode(node, \"MetaProperty\")\n};\n\npp$5.parseLiteral = function(value) {\n var node = this.startNode();\n node.value = value;\n node.raw = this.input.slice(this.start, this.end);\n if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1).replace(/_/g, \"\"); }\n this.next();\n return this.finishNode(node, \"Literal\")\n};\n\npp$5.parseParenExpression = function() {\n this.expect(types$1.parenL);\n var val = this.parseExpression();\n this.expect(types$1.parenR);\n return val\n};\n\npp$5.parseParenAndDistinguishExpression = function(canBeArrow, forInit) {\n var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;\n if (this.options.ecmaVersion >= 6) {\n this.next();\n\n var innerStartPos = this.start, innerStartLoc = this.startLoc;\n var exprList = [], first = true, lastIsComma = false;\n var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;\n this.yieldPos = 0;\n this.awaitPos = 0;\n // Do not save awaitIdentPos to allow checking awaits nested in parameters\n while (this.type !== types$1.parenR) {\n first ? first = false : this.expect(types$1.comma);\n if (allowTrailingComma && this.afterTrailingComma(types$1.parenR, true)) {\n lastIsComma = true;\n break\n } else if (this.type === types$1.ellipsis) {\n spreadStart = this.start;\n exprList.push(this.parseParenItem(this.parseRestBinding()));\n if (this.type === types$1.comma) { this.raise(this.start, \"Comma is not permitted after the rest element\"); }\n break\n } else {\n exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem));\n }\n }\n var innerEndPos = this.lastTokEnd, innerEndLoc = this.lastTokEndLoc;\n this.expect(types$1.parenR);\n\n if (canBeArrow && !this.canInsertSemicolon() && this.eat(types$1.arrow)) {\n this.checkPatternErrors(refDestructuringErrors, false);\n this.checkYieldAwaitInDefaultParams();\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n return this.parseParenArrowList(startPos, startLoc, exprList, forInit)\n }\n\n if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }\n if (spreadStart) { this.unexpected(spreadStart); }\n this.checkExpressionErrors(refDestructuringErrors, true);\n this.yieldPos = oldYieldPos || this.yieldPos;\n this.awaitPos = oldAwaitPos || this.awaitPos;\n\n if (exprList.length > 1) {\n val = this.startNodeAt(innerStartPos, innerStartLoc);\n val.expressions = exprList;\n this.finishNodeAt(val, \"SequenceExpression\", innerEndPos, innerEndLoc);\n } else {\n val = exprList[0];\n }\n } else {\n val = this.parseParenExpression();\n }\n\n if (this.options.preserveParens) {\n var par = this.startNodeAt(startPos, startLoc);\n par.expression = val;\n return this.finishNode(par, \"ParenthesizedExpression\")\n } else {\n return val\n }\n};\n\npp$5.parseParenItem = function(item) {\n return item\n};\n\npp$5.parseParenArrowList = function(startPos, startLoc, exprList, forInit) {\n return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, false, forInit)\n};\n\n// New's precedence is slightly tricky. It must allow its argument to\n// be a `[]` or dot subscript expression, but not a call — at least,\n// not without wrapping it in parentheses. Thus, it uses the noCalls\n// argument to parseSubscripts to prevent it from consuming the\n// argument list.\n\nvar empty = [];\n\npp$5.parseNew = function() {\n if (this.containsEsc) { this.raiseRecoverable(this.start, \"Escape sequence in keyword new\"); }\n var node = this.startNode();\n var meta = this.parseIdent(true);\n if (this.options.ecmaVersion >= 6 && this.eat(types$1.dot)) {\n node.meta = meta;\n var containsEsc = this.containsEsc;\n node.property = this.parseIdent(true);\n if (node.property.name !== \"target\")\n { this.raiseRecoverable(node.property.start, \"The only valid meta property for new is 'new.target'\"); }\n if (containsEsc)\n { this.raiseRecoverable(node.start, \"'new.target' must not contain escaped characters\"); }\n if (!this.allowNewDotTarget)\n { this.raiseRecoverable(node.start, \"'new.target' can only be used in functions and class static block\"); }\n return this.finishNode(node, \"MetaProperty\")\n }\n var startPos = this.start, startLoc = this.startLoc, isImport = this.type === types$1._import;\n node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true, false);\n if (isImport && node.callee.type === \"ImportExpression\") {\n this.raise(startPos, \"Cannot use new with import()\");\n }\n if (this.eat(types$1.parenL)) { node.arguments = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false); }\n else { node.arguments = empty; }\n return this.finishNode(node, \"NewExpression\")\n};\n\n// Parse template expression.\n\npp$5.parseTemplateElement = function(ref) {\n var isTagged = ref.isTagged;\n\n var elem = this.startNode();\n if (this.type === types$1.invalidTemplate) {\n if (!isTagged) {\n this.raiseRecoverable(this.start, \"Bad escape sequence in untagged template literal\");\n }\n elem.value = {\n raw: this.value,\n cooked: null\n };\n } else {\n elem.value = {\n raw: this.input.slice(this.start, this.end).replace(/\\r\\n?/g, \"\\n\"),\n cooked: this.value\n };\n }\n this.next();\n elem.tail = this.type === types$1.backQuote;\n return this.finishNode(elem, \"TemplateElement\")\n};\n\npp$5.parseTemplate = function(ref) {\n if ( ref === void 0 ) ref = {};\n var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;\n\n var node = this.startNode();\n this.next();\n node.expressions = [];\n var curElt = this.parseTemplateElement({isTagged: isTagged});\n node.quasis = [curElt];\n while (!curElt.tail) {\n if (this.type === types$1.eof) { this.raise(this.pos, \"Unterminated template literal\"); }\n this.expect(types$1.dollarBraceL);\n node.expressions.push(this.parseExpression());\n this.expect(types$1.braceR);\n node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged}));\n }\n this.next();\n return this.finishNode(node, \"TemplateLiteral\")\n};\n\npp$5.isAsyncProp = function(prop) {\n return !prop.computed && prop.key.type === \"Identifier\" && prop.key.name === \"async\" &&\n (this.type === types$1.name || this.type === types$1.num || this.type === types$1.string || this.type === types$1.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types$1.star)) &&\n !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))\n};\n\n// Parse an object literal or binding pattern.\n\npp$5.parseObj = function(isPattern, refDestructuringErrors) {\n var node = this.startNode(), first = true, propHash = {};\n node.properties = [];\n this.next();\n while (!this.eat(types$1.braceR)) {\n if (!first) {\n this.expect(types$1.comma);\n if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types$1.braceR)) { break }\n } else { first = false; }\n\n var prop = this.parseProperty(isPattern, refDestructuringErrors);\n if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); }\n node.properties.push(prop);\n }\n return this.finishNode(node, isPattern ? \"ObjectPattern\" : \"ObjectExpression\")\n};\n\npp$5.parseProperty = function(isPattern, refDestructuringErrors) {\n var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;\n if (this.options.ecmaVersion >= 9 && this.eat(types$1.ellipsis)) {\n if (isPattern) {\n prop.argument = this.parseIdent(false);\n if (this.type === types$1.comma) {\n this.raise(this.start, \"Comma is not permitted after the rest element\");\n }\n return this.finishNode(prop, \"RestElement\")\n }\n // Parse argument.\n prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);\n // To disallow trailing comma via `this.toAssignable()`.\n if (this.type === types$1.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {\n refDestructuringErrors.trailingComma = this.start;\n }\n // Finish\n return this.finishNode(prop, \"SpreadElement\")\n }\n if (this.options.ecmaVersion >= 6) {\n prop.method = false;\n prop.shorthand = false;\n if (isPattern || refDestructuringErrors) {\n startPos = this.start;\n startLoc = this.startLoc;\n }\n if (!isPattern)\n { isGenerator = this.eat(types$1.star); }\n }\n var containsEsc = this.containsEsc;\n this.parsePropertyName(prop);\n if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {\n isAsync = true;\n isGenerator = this.options.ecmaVersion >= 9 && this.eat(types$1.star);\n this.parsePropertyName(prop);\n } else {\n isAsync = false;\n }\n this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);\n return this.finishNode(prop, \"Property\")\n};\n\npp$5.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {\n if ((isGenerator || isAsync) && this.type === types$1.colon)\n { this.unexpected(); }\n\n if (this.eat(types$1.colon)) {\n prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);\n prop.kind = \"init\";\n } else if (this.options.ecmaVersion >= 6 && this.type === types$1.parenL) {\n if (isPattern) { this.unexpected(); }\n prop.kind = \"init\";\n prop.method = true;\n prop.value = this.parseMethod(isGenerator, isAsync);\n } else if (!isPattern && !containsEsc &&\n this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === \"Identifier\" &&\n (prop.key.name === \"get\" || prop.key.name === \"set\") &&\n (this.type !== types$1.comma && this.type !== types$1.braceR && this.type !== types$1.eq)) {\n if (isGenerator || isAsync) { this.unexpected(); }\n prop.kind = prop.key.name;\n this.parsePropertyName(prop);\n prop.value = this.parseMethod(false);\n var paramCount = prop.kind === \"get\" ? 0 : 1;\n if (prop.value.params.length !== paramCount) {\n var start = prop.value.start;\n if (prop.kind === \"get\")\n { this.raiseRecoverable(start, \"getter should have no params\"); }\n else\n { this.raiseRecoverable(start, \"setter should have exactly one param\"); }\n } else {\n if (prop.kind === \"set\" && prop.value.params[0].type === \"RestElement\")\n { this.raiseRecoverable(prop.value.params[0].start, \"Setter cannot use rest params\"); }\n }\n } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === \"Identifier\") {\n if (isGenerator || isAsync) { this.unexpected(); }\n this.checkUnreserved(prop.key);\n if (prop.key.name === \"await\" && !this.awaitIdentPos)\n { this.awaitIdentPos = startPos; }\n prop.kind = \"init\";\n if (isPattern) {\n prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key));\n } else if (this.type === types$1.eq && refDestructuringErrors) {\n if (refDestructuringErrors.shorthandAssign < 0)\n { refDestructuringErrors.shorthandAssign = this.start; }\n prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key));\n } else {\n prop.value = this.copyNode(prop.key);\n }\n prop.shorthand = true;\n } else { this.unexpected(); }\n};\n\npp$5.parsePropertyName = function(prop) {\n if (this.options.ecmaVersion >= 6) {\n if (this.eat(types$1.bracketL)) {\n prop.computed = true;\n prop.key = this.parseMaybeAssign();\n this.expect(types$1.bracketR);\n return prop.key\n } else {\n prop.computed = false;\n }\n }\n return prop.key = this.type === types$1.num || this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== \"never\")\n};\n\n// Initialize empty function node.\n\npp$5.initFunction = function(node) {\n node.id = null;\n if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; }\n if (this.options.ecmaVersion >= 8) { node.async = false; }\n};\n\n// Parse object or class method.\n\npp$5.parseMethod = function(isGenerator, isAsync, allowDirectSuper) {\n var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;\n\n this.initFunction(node);\n if (this.options.ecmaVersion >= 6)\n { node.generator = isGenerator; }\n if (this.options.ecmaVersion >= 8)\n { node.async = !!isAsync; }\n\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.awaitIdentPos = 0;\n this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0));\n\n this.expect(types$1.parenL);\n node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8);\n this.checkYieldAwaitInDefaultParams();\n this.parseFunctionBody(node, false, true, false);\n\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.awaitIdentPos = oldAwaitIdentPos;\n return this.finishNode(node, \"FunctionExpression\")\n};\n\n// Parse arrow function expression with given parameters.\n\npp$5.parseArrowExpression = function(node, params, isAsync, forInit) {\n var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;\n\n this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW);\n this.initFunction(node);\n if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; }\n\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.awaitIdentPos = 0;\n\n node.params = this.toAssignableList(params, true);\n this.parseFunctionBody(node, true, false, forInit);\n\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.awaitIdentPos = oldAwaitIdentPos;\n return this.finishNode(node, \"ArrowFunctionExpression\")\n};\n\n// Parse function body and check parameters.\n\npp$5.parseFunctionBody = function(node, isArrowFunction, isMethod, forInit) {\n var isExpression = isArrowFunction && this.type !== types$1.braceL;\n var oldStrict = this.strict, useStrict = false;\n\n if (isExpression) {\n node.body = this.parseMaybeAssign(forInit);\n node.expression = true;\n this.checkParams(node, false);\n } else {\n var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);\n if (!oldStrict || nonSimple) {\n useStrict = this.strictDirective(this.end);\n // If this is a strict mode function, verify that argument names\n // are not repeated, and it does not try to bind the words `eval`\n // or `arguments`.\n if (useStrict && nonSimple)\n { this.raiseRecoverable(node.start, \"Illegal 'use strict' directive in function with non-simple parameter list\"); }\n }\n // Start a new scope with regard to labels and the `inFunction`\n // flag (restore them to their old value afterwards).\n var oldLabels = this.labels;\n this.labels = [];\n if (useStrict) { this.strict = true; }\n\n // Add the params to varDeclaredNames to ensure that an error is thrown\n // if a let/const declaration in the function clashes with one of the params.\n this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params));\n // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'\n if (this.strict && node.id) { this.checkLValSimple(node.id, BIND_OUTSIDE); }\n node.body = this.parseBlock(false, undefined, useStrict && !oldStrict);\n node.expression = false;\n this.adaptDirectivePrologue(node.body.body);\n this.labels = oldLabels;\n }\n this.exitScope();\n};\n\npp$5.isSimpleParamList = function(params) {\n for (var i = 0, list = params; i < list.length; i += 1)\n {\n var param = list[i];\n\n if (param.type !== \"Identifier\") { return false\n } }\n return true\n};\n\n// Checks function params for various disallowed patterns such as using \"eval\"\n// or \"arguments\" and duplicate parameters.\n\npp$5.checkParams = function(node, allowDuplicates) {\n var nameHash = Object.create(null);\n for (var i = 0, list = node.params; i < list.length; i += 1)\n {\n var param = list[i];\n\n this.checkLValInnerPattern(param, BIND_VAR, allowDuplicates ? null : nameHash);\n }\n};\n\n// Parses a comma-separated list of expressions, and returns them as\n// an array. `close` is the token type that ends the list, and\n// `allowEmpty` can be turned on to allow subsequent commas with\n// nothing in between them to be parsed as `null` (which is needed\n// for array literals).\n\npp$5.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {\n var elts = [], first = true;\n while (!this.eat(close)) {\n if (!first) {\n this.expect(types$1.comma);\n if (allowTrailingComma && this.afterTrailingComma(close)) { break }\n } else { first = false; }\n\n var elt = (void 0);\n if (allowEmpty && this.type === types$1.comma)\n { elt = null; }\n else if (this.type === types$1.ellipsis) {\n elt = this.parseSpread(refDestructuringErrors);\n if (refDestructuringErrors && this.type === types$1.comma && refDestructuringErrors.trailingComma < 0)\n { refDestructuringErrors.trailingComma = this.start; }\n } else {\n elt = this.parseMaybeAssign(false, refDestructuringErrors);\n }\n elts.push(elt);\n }\n return elts\n};\n\npp$5.checkUnreserved = function(ref) {\n var start = ref.start;\n var end = ref.end;\n var name = ref.name;\n\n if (this.inGenerator && name === \"yield\")\n { this.raiseRecoverable(start, \"Cannot use 'yield' as identifier inside a generator\"); }\n if (this.inAsync && name === \"await\")\n { this.raiseRecoverable(start, \"Cannot use 'await' as identifier inside an async function\"); }\n if (this.currentThisScope().inClassFieldInit && name === \"arguments\")\n { this.raiseRecoverable(start, \"Cannot use 'arguments' in class field initializer\"); }\n if (this.inClassStaticBlock && (name === \"arguments\" || name === \"await\"))\n { this.raise(start, (\"Cannot use \" + name + \" in class static initialization block\")); }\n if (this.keywords.test(name))\n { this.raise(start, (\"Unexpected keyword '\" + name + \"'\")); }\n if (this.options.ecmaVersion < 6 &&\n this.input.slice(start, end).indexOf(\"\\\\\") !== -1) { return }\n var re = this.strict ? this.reservedWordsStrict : this.reservedWords;\n if (re.test(name)) {\n if (!this.inAsync && name === \"await\")\n { this.raiseRecoverable(start, \"Cannot use keyword 'await' outside an async function\"); }\n this.raiseRecoverable(start, (\"The keyword '\" + name + \"' is reserved\"));\n }\n};\n\n// Parse the next token as an identifier. If `liberal` is true (used\n// when parsing properties), it will also convert keywords into\n// identifiers.\n\npp$5.parseIdent = function(liberal) {\n var node = this.startNode();\n if (this.type === types$1.name) {\n node.name = this.value;\n } else if (this.type.keyword) {\n node.name = this.type.keyword;\n\n // To fix https://github.com/acornjs/acorn/issues/575\n // `class` and `function` keywords push new context into this.context.\n // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.\n // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword\n if ((node.name === \"class\" || node.name === \"function\") &&\n (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {\n this.context.pop();\n }\n } else {\n this.unexpected();\n }\n this.next(!!liberal);\n this.finishNode(node, \"Identifier\");\n if (!liberal) {\n this.checkUnreserved(node);\n if (node.name === \"await\" && !this.awaitIdentPos)\n { this.awaitIdentPos = node.start; }\n }\n return node\n};\n\npp$5.parsePrivateIdent = function() {\n var node = this.startNode();\n if (this.type === types$1.privateId) {\n node.name = this.value;\n } else {\n this.unexpected();\n }\n this.next();\n this.finishNode(node, \"PrivateIdentifier\");\n\n // For validating existence\n if (this.privateNameStack.length === 0) {\n this.raise(node.start, (\"Private field '#\" + (node.name) + \"' must be declared in an enclosing class\"));\n } else {\n this.privateNameStack[this.privateNameStack.length - 1].used.push(node);\n }\n\n return node\n};\n\n// Parses yield expression inside generator.\n\npp$5.parseYield = function(forInit) {\n if (!this.yieldPos) { this.yieldPos = this.start; }\n\n var node = this.startNode();\n this.next();\n if (this.type === types$1.semi || this.canInsertSemicolon() || (this.type !== types$1.star && !this.type.startsExpr)) {\n node.delegate = false;\n node.argument = null;\n } else {\n node.delegate = this.eat(types$1.star);\n node.argument = this.parseMaybeAssign(forInit);\n }\n return this.finishNode(node, \"YieldExpression\")\n};\n\npp$5.parseAwait = function(forInit) {\n if (!this.awaitPos) { this.awaitPos = this.start; }\n\n var node = this.startNode();\n this.next();\n node.argument = this.parseMaybeUnary(null, true, false, forInit);\n return this.finishNode(node, \"AwaitExpression\")\n};\n\nvar pp$4 = Parser.prototype;\n\n// This function is used to raise exceptions on parse errors. It\n// takes an offset integer (into the current `input`) to indicate\n// the location of the error, attaches the position to the end\n// of the error message, and then raises a `SyntaxError` with that\n// message.\n\npp$4.raise = function(pos, message) {\n var loc = getLineInfo(this.input, pos);\n message += \" (\" + loc.line + \":\" + loc.column + \")\";\n var err = new SyntaxError(message);\n err.pos = pos; err.loc = loc; err.raisedAt = this.pos;\n throw err\n};\n\npp$4.raiseRecoverable = pp$4.raise;\n\npp$4.curPosition = function() {\n if (this.options.locations) {\n return new Position(this.curLine, this.pos - this.lineStart)\n }\n};\n\nvar pp$3 = Parser.prototype;\n\nvar Scope = function Scope(flags) {\n this.flags = flags;\n // A list of var-declared names in the current lexical scope\n this.var = [];\n // A list of lexically-declared names in the current lexical scope\n this.lexical = [];\n // A list of lexically-declared FunctionDeclaration names in the current lexical scope\n this.functions = [];\n // A switch to disallow the identifier reference 'arguments'\n this.inClassFieldInit = false;\n};\n\n// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.\n\npp$3.enterScope = function(flags) {\n this.scopeStack.push(new Scope(flags));\n};\n\npp$3.exitScope = function() {\n this.scopeStack.pop();\n};\n\n// The spec says:\n// > At the top level of a function, or script, function declarations are\n// > treated like var declarations rather than like lexical declarations.\npp$3.treatFunctionsAsVarInScope = function(scope) {\n return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP)\n};\n\npp$3.declareName = function(name, bindingType, pos) {\n var redeclared = false;\n if (bindingType === BIND_LEXICAL) {\n var scope = this.currentScope();\n redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1;\n scope.lexical.push(name);\n if (this.inModule && (scope.flags & SCOPE_TOP))\n { delete this.undefinedExports[name]; }\n } else if (bindingType === BIND_SIMPLE_CATCH) {\n var scope$1 = this.currentScope();\n scope$1.lexical.push(name);\n } else if (bindingType === BIND_FUNCTION) {\n var scope$2 = this.currentScope();\n if (this.treatFunctionsAsVar)\n { redeclared = scope$2.lexical.indexOf(name) > -1; }\n else\n { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; }\n scope$2.functions.push(name);\n } else {\n for (var i = this.scopeStack.length - 1; i >= 0; --i) {\n var scope$3 = this.scopeStack[i];\n if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) ||\n !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) {\n redeclared = true;\n break\n }\n scope$3.var.push(name);\n if (this.inModule && (scope$3.flags & SCOPE_TOP))\n { delete this.undefinedExports[name]; }\n if (scope$3.flags & SCOPE_VAR) { break }\n }\n }\n if (redeclared) { this.raiseRecoverable(pos, (\"Identifier '\" + name + \"' has already been declared\")); }\n};\n\npp$3.checkLocalExport = function(id) {\n // scope.functions must be empty as Module code is always strict.\n if (this.scopeStack[0].lexical.indexOf(id.name) === -1 &&\n this.scopeStack[0].var.indexOf(id.name) === -1) {\n this.undefinedExports[id.name] = id;\n }\n};\n\npp$3.currentScope = function() {\n return this.scopeStack[this.scopeStack.length - 1]\n};\n\npp$3.currentVarScope = function() {\n for (var i = this.scopeStack.length - 1;; i--) {\n var scope = this.scopeStack[i];\n if (scope.flags & SCOPE_VAR) { return scope }\n }\n};\n\n// Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`.\npp$3.currentThisScope = function() {\n for (var i = this.scopeStack.length - 1;; i--) {\n var scope = this.scopeStack[i];\n if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope }\n }\n};\n\nvar Node = function Node(parser, pos, loc) {\n this.type = \"\";\n this.start = pos;\n this.end = 0;\n if (parser.options.locations)\n { this.loc = new SourceLocation(parser, loc); }\n if (parser.options.directSourceFile)\n { this.sourceFile = parser.options.directSourceFile; }\n if (parser.options.ranges)\n { this.range = [pos, 0]; }\n};\n\n// Start an AST node, attaching a start offset.\n\nvar pp$2 = Parser.prototype;\n\npp$2.startNode = function() {\n return new Node(this, this.start, this.startLoc)\n};\n\npp$2.startNodeAt = function(pos, loc) {\n return new Node(this, pos, loc)\n};\n\n// Finish an AST node, adding `type` and `end` properties.\n\nfunction finishNodeAt(node, type, pos, loc) {\n node.type = type;\n node.end = pos;\n if (this.options.locations)\n { node.loc.end = loc; }\n if (this.options.ranges)\n { node.range[1] = pos; }\n return node\n}\n\npp$2.finishNode = function(node, type) {\n return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)\n};\n\n// Finish node at given position\n\npp$2.finishNodeAt = function(node, type, pos, loc) {\n return finishNodeAt.call(this, node, type, pos, loc)\n};\n\npp$2.copyNode = function(node) {\n var newNode = new Node(this, node.start, this.startLoc);\n for (var prop in node) { newNode[prop] = node[prop]; }\n return newNode\n};\n\n// This file contains Unicode properties extracted from the ECMAScript specification.\n// The lists are extracted like so:\n// $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText)\n\n// #table-binary-unicode-properties\nvar ecma9BinaryProperties = \"ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS\";\nvar ecma10BinaryProperties = ecma9BinaryProperties + \" Extended_Pictographic\";\nvar ecma11BinaryProperties = ecma10BinaryProperties;\nvar ecma12BinaryProperties = ecma11BinaryProperties + \" EBase EComp EMod EPres ExtPict\";\nvar ecma13BinaryProperties = ecma12BinaryProperties;\nvar ecma14BinaryProperties = ecma13BinaryProperties;\n\nvar unicodeBinaryProperties = {\n 9: ecma9BinaryProperties,\n 10: ecma10BinaryProperties,\n 11: ecma11BinaryProperties,\n 12: ecma12BinaryProperties,\n 13: ecma13BinaryProperties,\n 14: ecma14BinaryProperties\n};\n\n// #table-unicode-general-category-values\nvar unicodeGeneralCategoryValues = \"Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu\";\n\n// #table-unicode-script-values\nvar ecma9ScriptValues = \"Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb\";\nvar ecma10ScriptValues = ecma9ScriptValues + \" Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd\";\nvar ecma11ScriptValues = ecma10ScriptValues + \" Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho\";\nvar ecma12ScriptValues = ecma11ScriptValues + \" Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi\";\nvar ecma13ScriptValues = ecma12ScriptValues + \" Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith\";\nvar ecma14ScriptValues = ecma13ScriptValues + \" Kawi Nag_Mundari Nagm\";\n\nvar unicodeScriptValues = {\n 9: ecma9ScriptValues,\n 10: ecma10ScriptValues,\n 11: ecma11ScriptValues,\n 12: ecma12ScriptValues,\n 13: ecma13ScriptValues,\n 14: ecma14ScriptValues\n};\n\nvar data = {};\nfunction buildUnicodeData(ecmaVersion) {\n var d = data[ecmaVersion] = {\n binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + \" \" + unicodeGeneralCategoryValues),\n nonBinary: {\n General_Category: wordsRegexp(unicodeGeneralCategoryValues),\n Script: wordsRegexp(unicodeScriptValues[ecmaVersion])\n }\n };\n d.nonBinary.Script_Extensions = d.nonBinary.Script;\n\n d.nonBinary.gc = d.nonBinary.General_Category;\n d.nonBinary.sc = d.nonBinary.Script;\n d.nonBinary.scx = d.nonBinary.Script_Extensions;\n}\n\nfor (var i = 0, list = [9, 10, 11, 12, 13, 14]; i < list.length; i += 1) {\n var ecmaVersion = list[i];\n\n buildUnicodeData(ecmaVersion);\n}\n\nvar pp$1 = Parser.prototype;\n\nvar RegExpValidationState = function RegExpValidationState(parser) {\n this.parser = parser;\n this.validFlags = \"gim\" + (parser.options.ecmaVersion >= 6 ? \"uy\" : \"\") + (parser.options.ecmaVersion >= 9 ? \"s\" : \"\") + (parser.options.ecmaVersion >= 13 ? \"d\" : \"\");\n this.unicodeProperties = data[parser.options.ecmaVersion >= 14 ? 14 : parser.options.ecmaVersion];\n this.source = \"\";\n this.flags = \"\";\n this.start = 0;\n this.switchU = false;\n this.switchN = false;\n this.pos = 0;\n this.lastIntValue = 0;\n this.lastStringValue = \"\";\n this.lastAssertionIsQuantifiable = false;\n this.numCapturingParens = 0;\n this.maxBackReference = 0;\n this.groupNames = [];\n this.backReferenceNames = [];\n};\n\nRegExpValidationState.prototype.reset = function reset (start, pattern, flags) {\n var unicode = flags.indexOf(\"u\") !== -1;\n this.start = start | 0;\n this.source = pattern + \"\";\n this.flags = flags;\n this.switchU = unicode && this.parser.options.ecmaVersion >= 6;\n this.switchN = unicode && this.parser.options.ecmaVersion >= 9;\n};\n\nRegExpValidationState.prototype.raise = function raise (message) {\n this.parser.raiseRecoverable(this.start, (\"Invalid regular expression: /\" + (this.source) + \"/: \" + message));\n};\n\n// If u flag is given, this returns the code point at the index (it combines a surrogate pair).\n// Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).\nRegExpValidationState.prototype.at = function at (i, forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n var s = this.source;\n var l = s.length;\n if (i >= l) {\n return -1\n }\n var c = s.charCodeAt(i);\n if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {\n return c\n }\n var next = s.charCodeAt(i + 1);\n return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c\n};\n\nRegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n var s = this.source;\n var l = s.length;\n if (i >= l) {\n return l\n }\n var c = s.charCodeAt(i), next;\n if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l ||\n (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) {\n return i + 1\n }\n return i + 2\n};\n\nRegExpValidationState.prototype.current = function current (forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n return this.at(this.pos, forceU)\n};\n\nRegExpValidationState.prototype.lookahead = function lookahead (forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n return this.at(this.nextIndex(this.pos, forceU), forceU)\n};\n\nRegExpValidationState.prototype.advance = function advance (forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n this.pos = this.nextIndex(this.pos, forceU);\n};\n\nRegExpValidationState.prototype.eat = function eat (ch, forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n if (this.current(forceU) === ch) {\n this.advance(forceU);\n return true\n }\n return false\n};\n\n/**\n * Validate the flags part of a given RegExpLiteral.\n *\n * @param {RegExpValidationState} state The state to validate RegExp.\n * @returns {void}\n */\npp$1.validateRegExpFlags = function(state) {\n var validFlags = state.validFlags;\n var flags = state.flags;\n\n for (var i = 0; i < flags.length; i++) {\n var flag = flags.charAt(i);\n if (validFlags.indexOf(flag) === -1) {\n this.raise(state.start, \"Invalid regular expression flag\");\n }\n if (flags.indexOf(flag, i + 1) > -1) {\n this.raise(state.start, \"Duplicate regular expression flag\");\n }\n }\n};\n\n/**\n * Validate the pattern part of a given RegExpLiteral.\n *\n * @param {RegExpValidationState} state The state to validate RegExp.\n * @returns {void}\n */\npp$1.validateRegExpPattern = function(state) {\n this.regexp_pattern(state);\n\n // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of\n // parsing contains a |GroupName|, reparse with the goal symbol\n // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*\n // exception if _P_ did not conform to the grammar, if any elements of _P_\n // were not matched by the parse, or if any Early Error conditions exist.\n if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) {\n state.switchN = true;\n this.regexp_pattern(state);\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern\npp$1.regexp_pattern = function(state) {\n state.pos = 0;\n state.lastIntValue = 0;\n state.lastStringValue = \"\";\n state.lastAssertionIsQuantifiable = false;\n state.numCapturingParens = 0;\n state.maxBackReference = 0;\n state.groupNames.length = 0;\n state.backReferenceNames.length = 0;\n\n this.regexp_disjunction(state);\n\n if (state.pos !== state.source.length) {\n // Make the same messages as V8.\n if (state.eat(0x29 /* ) */)) {\n state.raise(\"Unmatched ')'\");\n }\n if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) {\n state.raise(\"Lone quantifier brackets\");\n }\n }\n if (state.maxBackReference > state.numCapturingParens) {\n state.raise(\"Invalid escape\");\n }\n for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {\n var name = list[i];\n\n if (state.groupNames.indexOf(name) === -1) {\n state.raise(\"Invalid named capture referenced\");\n }\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction\npp$1.regexp_disjunction = function(state) {\n this.regexp_alternative(state);\n while (state.eat(0x7C /* | */)) {\n this.regexp_alternative(state);\n }\n\n // Make the same message as V8.\n if (this.regexp_eatQuantifier(state, true)) {\n state.raise(\"Nothing to repeat\");\n }\n if (state.eat(0x7B /* { */)) {\n state.raise(\"Lone quantifier brackets\");\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative\npp$1.regexp_alternative = function(state) {\n while (state.pos < state.source.length && this.regexp_eatTerm(state))\n { }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term\npp$1.regexp_eatTerm = function(state) {\n if (this.regexp_eatAssertion(state)) {\n // Handle `QuantifiableAssertion Quantifier` alternative.\n // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion\n // is a QuantifiableAssertion.\n if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {\n // Make the same message as V8.\n if (state.switchU) {\n state.raise(\"Invalid quantifier\");\n }\n }\n return true\n }\n\n if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {\n this.regexp_eatQuantifier(state);\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion\npp$1.regexp_eatAssertion = function(state) {\n var start = state.pos;\n state.lastAssertionIsQuantifiable = false;\n\n // ^, $\n if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {\n return true\n }\n\n // \\b \\B\n if (state.eat(0x5C /* \\ */)) {\n if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {\n return true\n }\n state.pos = start;\n }\n\n // Lookahead / Lookbehind\n if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {\n var lookbehind = false;\n if (this.options.ecmaVersion >= 9) {\n lookbehind = state.eat(0x3C /* < */);\n }\n if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {\n this.regexp_disjunction(state);\n if (!state.eat(0x29 /* ) */)) {\n state.raise(\"Unterminated group\");\n }\n state.lastAssertionIsQuantifiable = !lookbehind;\n return true\n }\n }\n\n state.pos = start;\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier\npp$1.regexp_eatQuantifier = function(state, noError) {\n if ( noError === void 0 ) noError = false;\n\n if (this.regexp_eatQuantifierPrefix(state, noError)) {\n state.eat(0x3F /* ? */);\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix\npp$1.regexp_eatQuantifierPrefix = function(state, noError) {\n return (\n state.eat(0x2A /* * */) ||\n state.eat(0x2B /* + */) ||\n state.eat(0x3F /* ? */) ||\n this.regexp_eatBracedQuantifier(state, noError)\n )\n};\npp$1.regexp_eatBracedQuantifier = function(state, noError) {\n var start = state.pos;\n if (state.eat(0x7B /* { */)) {\n var min = 0, max = -1;\n if (this.regexp_eatDecimalDigits(state)) {\n min = state.lastIntValue;\n if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {\n max = state.lastIntValue;\n }\n if (state.eat(0x7D /* } */)) {\n // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term\n if (max !== -1 && max < min && !noError) {\n state.raise(\"numbers out of order in {} quantifier\");\n }\n return true\n }\n }\n if (state.switchU && !noError) {\n state.raise(\"Incomplete quantifier\");\n }\n state.pos = start;\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Atom\npp$1.regexp_eatAtom = function(state) {\n return (\n this.regexp_eatPatternCharacters(state) ||\n state.eat(0x2E /* . */) ||\n this.regexp_eatReverseSolidusAtomEscape(state) ||\n this.regexp_eatCharacterClass(state) ||\n this.regexp_eatUncapturingGroup(state) ||\n this.regexp_eatCapturingGroup(state)\n )\n};\npp$1.regexp_eatReverseSolidusAtomEscape = function(state) {\n var start = state.pos;\n if (state.eat(0x5C /* \\ */)) {\n if (this.regexp_eatAtomEscape(state)) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$1.regexp_eatUncapturingGroup = function(state) {\n var start = state.pos;\n if (state.eat(0x28 /* ( */)) {\n if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) {\n this.regexp_disjunction(state);\n if (state.eat(0x29 /* ) */)) {\n return true\n }\n state.raise(\"Unterminated group\");\n }\n state.pos = start;\n }\n return false\n};\npp$1.regexp_eatCapturingGroup = function(state) {\n if (state.eat(0x28 /* ( */)) {\n if (this.options.ecmaVersion >= 9) {\n this.regexp_groupSpecifier(state);\n } else if (state.current() === 0x3F /* ? */) {\n state.raise(\"Invalid group\");\n }\n this.regexp_disjunction(state);\n if (state.eat(0x29 /* ) */)) {\n state.numCapturingParens += 1;\n return true\n }\n state.raise(\"Unterminated group\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom\npp$1.regexp_eatExtendedAtom = function(state) {\n return (\n state.eat(0x2E /* . */) ||\n this.regexp_eatReverseSolidusAtomEscape(state) ||\n this.regexp_eatCharacterClass(state) ||\n this.regexp_eatUncapturingGroup(state) ||\n this.regexp_eatCapturingGroup(state) ||\n this.regexp_eatInvalidBracedQuantifier(state) ||\n this.regexp_eatExtendedPatternCharacter(state)\n )\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier\npp$1.regexp_eatInvalidBracedQuantifier = function(state) {\n if (this.regexp_eatBracedQuantifier(state, true)) {\n state.raise(\"Nothing to repeat\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter\npp$1.regexp_eatSyntaxCharacter = function(state) {\n var ch = state.current();\n if (isSyntaxCharacter(ch)) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n return false\n};\nfunction isSyntaxCharacter(ch) {\n return (\n ch === 0x24 /* $ */ ||\n ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||\n ch === 0x2E /* . */ ||\n ch === 0x3F /* ? */ ||\n ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||\n ch >= 0x7B /* { */ && ch <= 0x7D /* } */\n )\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter\n// But eat eager.\npp$1.regexp_eatPatternCharacters = function(state) {\n var start = state.pos;\n var ch = 0;\n while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {\n state.advance();\n }\n return state.pos !== start\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter\npp$1.regexp_eatExtendedPatternCharacter = function(state) {\n var ch = state.current();\n if (\n ch !== -1 &&\n ch !== 0x24 /* $ */ &&\n !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&\n ch !== 0x2E /* . */ &&\n ch !== 0x3F /* ? */ &&\n ch !== 0x5B /* [ */ &&\n ch !== 0x5E /* ^ */ &&\n ch !== 0x7C /* | */\n ) {\n state.advance();\n return true\n }\n return false\n};\n\n// GroupSpecifier ::\n// [empty]\n// `?` GroupName\npp$1.regexp_groupSpecifier = function(state) {\n if (state.eat(0x3F /* ? */)) {\n if (this.regexp_eatGroupName(state)) {\n if (state.groupNames.indexOf(state.lastStringValue) !== -1) {\n state.raise(\"Duplicate capture group name\");\n }\n state.groupNames.push(state.lastStringValue);\n return\n }\n state.raise(\"Invalid group\");\n }\n};\n\n// GroupName ::\n// `<` RegExpIdentifierName `>`\n// Note: this updates `state.lastStringValue` property with the eaten name.\npp$1.regexp_eatGroupName = function(state) {\n state.lastStringValue = \"\";\n if (state.eat(0x3C /* < */)) {\n if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {\n return true\n }\n state.raise(\"Invalid capture group name\");\n }\n return false\n};\n\n// RegExpIdentifierName ::\n// RegExpIdentifierStart\n// RegExpIdentifierName RegExpIdentifierPart\n// Note: this updates `state.lastStringValue` property with the eaten name.\npp$1.regexp_eatRegExpIdentifierName = function(state) {\n state.lastStringValue = \"\";\n if (this.regexp_eatRegExpIdentifierStart(state)) {\n state.lastStringValue += codePointToString(state.lastIntValue);\n while (this.regexp_eatRegExpIdentifierPart(state)) {\n state.lastStringValue += codePointToString(state.lastIntValue);\n }\n return true\n }\n return false\n};\n\n// RegExpIdentifierStart ::\n// UnicodeIDStart\n// `$`\n// `_`\n// `\\` RegExpUnicodeEscapeSequence[+U]\npp$1.regexp_eatRegExpIdentifierStart = function(state) {\n var start = state.pos;\n var forceU = this.options.ecmaVersion >= 11;\n var ch = state.current(forceU);\n state.advance(forceU);\n\n if (ch === 0x5C /* \\ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {\n ch = state.lastIntValue;\n }\n if (isRegExpIdentifierStart(ch)) {\n state.lastIntValue = ch;\n return true\n }\n\n state.pos = start;\n return false\n};\nfunction isRegExpIdentifierStart(ch) {\n return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */\n}\n\n// RegExpIdentifierPart ::\n// UnicodeIDContinue\n// `$`\n// `_`\n// `\\` RegExpUnicodeEscapeSequence[+U]\n// \n// \npp$1.regexp_eatRegExpIdentifierPart = function(state) {\n var start = state.pos;\n var forceU = this.options.ecmaVersion >= 11;\n var ch = state.current(forceU);\n state.advance(forceU);\n\n if (ch === 0x5C /* \\ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {\n ch = state.lastIntValue;\n }\n if (isRegExpIdentifierPart(ch)) {\n state.lastIntValue = ch;\n return true\n }\n\n state.pos = start;\n return false\n};\nfunction isRegExpIdentifierPart(ch) {\n return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* */ || ch === 0x200D /* */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape\npp$1.regexp_eatAtomEscape = function(state) {\n if (\n this.regexp_eatBackReference(state) ||\n this.regexp_eatCharacterClassEscape(state) ||\n this.regexp_eatCharacterEscape(state) ||\n (state.switchN && this.regexp_eatKGroupName(state))\n ) {\n return true\n }\n if (state.switchU) {\n // Make the same message as V8.\n if (state.current() === 0x63 /* c */) {\n state.raise(\"Invalid unicode escape\");\n }\n state.raise(\"Invalid escape\");\n }\n return false\n};\npp$1.regexp_eatBackReference = function(state) {\n var start = state.pos;\n if (this.regexp_eatDecimalEscape(state)) {\n var n = state.lastIntValue;\n if (state.switchU) {\n // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape\n if (n > state.maxBackReference) {\n state.maxBackReference = n;\n }\n return true\n }\n if (n <= state.numCapturingParens) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$1.regexp_eatKGroupName = function(state) {\n if (state.eat(0x6B /* k */)) {\n if (this.regexp_eatGroupName(state)) {\n state.backReferenceNames.push(state.lastStringValue);\n return true\n }\n state.raise(\"Invalid named reference\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape\npp$1.regexp_eatCharacterEscape = function(state) {\n return (\n this.regexp_eatControlEscape(state) ||\n this.regexp_eatCControlLetter(state) ||\n this.regexp_eatZero(state) ||\n this.regexp_eatHexEscapeSequence(state) ||\n this.regexp_eatRegExpUnicodeEscapeSequence(state, false) ||\n (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||\n this.regexp_eatIdentityEscape(state)\n )\n};\npp$1.regexp_eatCControlLetter = function(state) {\n var start = state.pos;\n if (state.eat(0x63 /* c */)) {\n if (this.regexp_eatControlLetter(state)) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$1.regexp_eatZero = function(state) {\n if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {\n state.lastIntValue = 0;\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape\npp$1.regexp_eatControlEscape = function(state) {\n var ch = state.current();\n if (ch === 0x74 /* t */) {\n state.lastIntValue = 0x09; /* \\t */\n state.advance();\n return true\n }\n if (ch === 0x6E /* n */) {\n state.lastIntValue = 0x0A; /* \\n */\n state.advance();\n return true\n }\n if (ch === 0x76 /* v */) {\n state.lastIntValue = 0x0B; /* \\v */\n state.advance();\n return true\n }\n if (ch === 0x66 /* f */) {\n state.lastIntValue = 0x0C; /* \\f */\n state.advance();\n return true\n }\n if (ch === 0x72 /* r */) {\n state.lastIntValue = 0x0D; /* \\r */\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter\npp$1.regexp_eatControlLetter = function(state) {\n var ch = state.current();\n if (isControlLetter(ch)) {\n state.lastIntValue = ch % 0x20;\n state.advance();\n return true\n }\n return false\n};\nfunction isControlLetter(ch) {\n return (\n (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||\n (ch >= 0x61 /* a */ && ch <= 0x7A /* z */)\n )\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence\npp$1.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n var start = state.pos;\n var switchU = forceU || state.switchU;\n\n if (state.eat(0x75 /* u */)) {\n if (this.regexp_eatFixedHexDigits(state, 4)) {\n var lead = state.lastIntValue;\n if (switchU && lead >= 0xD800 && lead <= 0xDBFF) {\n var leadSurrogateEnd = state.pos;\n if (state.eat(0x5C /* \\ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {\n var trail = state.lastIntValue;\n if (trail >= 0xDC00 && trail <= 0xDFFF) {\n state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n return true\n }\n }\n state.pos = leadSurrogateEnd;\n state.lastIntValue = lead;\n }\n return true\n }\n if (\n switchU &&\n state.eat(0x7B /* { */) &&\n this.regexp_eatHexDigits(state) &&\n state.eat(0x7D /* } */) &&\n isValidUnicode(state.lastIntValue)\n ) {\n return true\n }\n if (switchU) {\n state.raise(\"Invalid unicode escape\");\n }\n state.pos = start;\n }\n\n return false\n};\nfunction isValidUnicode(ch) {\n return ch >= 0 && ch <= 0x10FFFF\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape\npp$1.regexp_eatIdentityEscape = function(state) {\n if (state.switchU) {\n if (this.regexp_eatSyntaxCharacter(state)) {\n return true\n }\n if (state.eat(0x2F /* / */)) {\n state.lastIntValue = 0x2F; /* / */\n return true\n }\n return false\n }\n\n var ch = state.current();\n if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape\npp$1.regexp_eatDecimalEscape = function(state) {\n state.lastIntValue = 0;\n var ch = state.current();\n if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {\n do {\n state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);\n state.advance();\n } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape\npp$1.regexp_eatCharacterClassEscape = function(state) {\n var ch = state.current();\n\n if (isCharacterClassEscape(ch)) {\n state.lastIntValue = -1;\n state.advance();\n return true\n }\n\n if (\n state.switchU &&\n this.options.ecmaVersion >= 9 &&\n (ch === 0x50 /* P */ || ch === 0x70 /* p */)\n ) {\n state.lastIntValue = -1;\n state.advance();\n if (\n state.eat(0x7B /* { */) &&\n this.regexp_eatUnicodePropertyValueExpression(state) &&\n state.eat(0x7D /* } */)\n ) {\n return true\n }\n state.raise(\"Invalid property name\");\n }\n\n return false\n};\nfunction isCharacterClassEscape(ch) {\n return (\n ch === 0x64 /* d */ ||\n ch === 0x44 /* D */ ||\n ch === 0x73 /* s */ ||\n ch === 0x53 /* S */ ||\n ch === 0x77 /* w */ ||\n ch === 0x57 /* W */\n )\n}\n\n// UnicodePropertyValueExpression ::\n// UnicodePropertyName `=` UnicodePropertyValue\n// LoneUnicodePropertyNameOrValue\npp$1.regexp_eatUnicodePropertyValueExpression = function(state) {\n var start = state.pos;\n\n // UnicodePropertyName `=` UnicodePropertyValue\n if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {\n var name = state.lastStringValue;\n if (this.regexp_eatUnicodePropertyValue(state)) {\n var value = state.lastStringValue;\n this.regexp_validateUnicodePropertyNameAndValue(state, name, value);\n return true\n }\n }\n state.pos = start;\n\n // LoneUnicodePropertyNameOrValue\n if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {\n var nameOrValue = state.lastStringValue;\n this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue);\n return true\n }\n return false\n};\npp$1.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {\n if (!hasOwn(state.unicodeProperties.nonBinary, name))\n { state.raise(\"Invalid property name\"); }\n if (!state.unicodeProperties.nonBinary[name].test(value))\n { state.raise(\"Invalid property value\"); }\n};\npp$1.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {\n if (!state.unicodeProperties.binary.test(nameOrValue))\n { state.raise(\"Invalid property name\"); }\n};\n\n// UnicodePropertyName ::\n// UnicodePropertyNameCharacters\npp$1.regexp_eatUnicodePropertyName = function(state) {\n var ch = 0;\n state.lastStringValue = \"\";\n while (isUnicodePropertyNameCharacter(ch = state.current())) {\n state.lastStringValue += codePointToString(ch);\n state.advance();\n }\n return state.lastStringValue !== \"\"\n};\nfunction isUnicodePropertyNameCharacter(ch) {\n return isControlLetter(ch) || ch === 0x5F /* _ */\n}\n\n// UnicodePropertyValue ::\n// UnicodePropertyValueCharacters\npp$1.regexp_eatUnicodePropertyValue = function(state) {\n var ch = 0;\n state.lastStringValue = \"\";\n while (isUnicodePropertyValueCharacter(ch = state.current())) {\n state.lastStringValue += codePointToString(ch);\n state.advance();\n }\n return state.lastStringValue !== \"\"\n};\nfunction isUnicodePropertyValueCharacter(ch) {\n return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)\n}\n\n// LoneUnicodePropertyNameOrValue ::\n// UnicodePropertyValueCharacters\npp$1.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {\n return this.regexp_eatUnicodePropertyValue(state)\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass\npp$1.regexp_eatCharacterClass = function(state) {\n if (state.eat(0x5B /* [ */)) {\n state.eat(0x5E /* ^ */);\n this.regexp_classRanges(state);\n if (state.eat(0x5D /* ] */)) {\n return true\n }\n // Unreachable since it threw \"unterminated regular expression\" error before.\n state.raise(\"Unterminated character class\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges\n// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges\n// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash\npp$1.regexp_classRanges = function(state) {\n while (this.regexp_eatClassAtom(state)) {\n var left = state.lastIntValue;\n if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) {\n var right = state.lastIntValue;\n if (state.switchU && (left === -1 || right === -1)) {\n state.raise(\"Invalid character class\");\n }\n if (left !== -1 && right !== -1 && left > right) {\n state.raise(\"Range out of order in character class\");\n }\n }\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash\npp$1.regexp_eatClassAtom = function(state) {\n var start = state.pos;\n\n if (state.eat(0x5C /* \\ */)) {\n if (this.regexp_eatClassEscape(state)) {\n return true\n }\n if (state.switchU) {\n // Make the same message as V8.\n var ch$1 = state.current();\n if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {\n state.raise(\"Invalid class escape\");\n }\n state.raise(\"Invalid escape\");\n }\n state.pos = start;\n }\n\n var ch = state.current();\n if (ch !== 0x5D /* ] */) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape\npp$1.regexp_eatClassEscape = function(state) {\n var start = state.pos;\n\n if (state.eat(0x62 /* b */)) {\n state.lastIntValue = 0x08; /* */\n return true\n }\n\n if (state.switchU && state.eat(0x2D /* - */)) {\n state.lastIntValue = 0x2D; /* - */\n return true\n }\n\n if (!state.switchU && state.eat(0x63 /* c */)) {\n if (this.regexp_eatClassControlLetter(state)) {\n return true\n }\n state.pos = start;\n }\n\n return (\n this.regexp_eatCharacterClassEscape(state) ||\n this.regexp_eatCharacterEscape(state)\n )\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter\npp$1.regexp_eatClassControlLetter = function(state) {\n var ch = state.current();\n if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {\n state.lastIntValue = ch % 0x20;\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence\npp$1.regexp_eatHexEscapeSequence = function(state) {\n var start = state.pos;\n if (state.eat(0x78 /* x */)) {\n if (this.regexp_eatFixedHexDigits(state, 2)) {\n return true\n }\n if (state.switchU) {\n state.raise(\"Invalid escape\");\n }\n state.pos = start;\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits\npp$1.regexp_eatDecimalDigits = function(state) {\n var start = state.pos;\n var ch = 0;\n state.lastIntValue = 0;\n while (isDecimalDigit(ch = state.current())) {\n state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);\n state.advance();\n }\n return state.pos !== start\n};\nfunction isDecimalDigit(ch) {\n return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits\npp$1.regexp_eatHexDigits = function(state) {\n var start = state.pos;\n var ch = 0;\n state.lastIntValue = 0;\n while (isHexDigit(ch = state.current())) {\n state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);\n state.advance();\n }\n return state.pos !== start\n};\nfunction isHexDigit(ch) {\n return (\n (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||\n (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||\n (ch >= 0x61 /* a */ && ch <= 0x66 /* f */)\n )\n}\nfunction hexToInt(ch) {\n if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {\n return 10 + (ch - 0x41 /* A */)\n }\n if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {\n return 10 + (ch - 0x61 /* a */)\n }\n return ch - 0x30 /* 0 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence\n// Allows only 0-377(octal) i.e. 0-255(decimal).\npp$1.regexp_eatLegacyOctalEscapeSequence = function(state) {\n if (this.regexp_eatOctalDigit(state)) {\n var n1 = state.lastIntValue;\n if (this.regexp_eatOctalDigit(state)) {\n var n2 = state.lastIntValue;\n if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {\n state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;\n } else {\n state.lastIntValue = n1 * 8 + n2;\n }\n } else {\n state.lastIntValue = n1;\n }\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit\npp$1.regexp_eatOctalDigit = function(state) {\n var ch = state.current();\n if (isOctalDigit(ch)) {\n state.lastIntValue = ch - 0x30; /* 0 */\n state.advance();\n return true\n }\n state.lastIntValue = 0;\n return false\n};\nfunction isOctalDigit(ch) {\n return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit\n// And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence\npp$1.regexp_eatFixedHexDigits = function(state, length) {\n var start = state.pos;\n state.lastIntValue = 0;\n for (var i = 0; i < length; ++i) {\n var ch = state.current();\n if (!isHexDigit(ch)) {\n state.pos = start;\n return false\n }\n state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);\n state.advance();\n }\n return true\n};\n\n// Object type used to represent tokens. Note that normally, tokens\n// simply exist as properties on the parser object. This is only\n// used for the onToken callback and the external tokenizer.\n\nvar Token = function Token(p) {\n this.type = p.type;\n this.value = p.value;\n this.start = p.start;\n this.end = p.end;\n if (p.options.locations)\n { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }\n if (p.options.ranges)\n { this.range = [p.start, p.end]; }\n};\n\n// ## Tokenizer\n\nvar pp = Parser.prototype;\n\n// Move to the next token\n\npp.next = function(ignoreEscapeSequenceInKeyword) {\n if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc)\n { this.raiseRecoverable(this.start, \"Escape sequence in keyword \" + this.type.keyword); }\n if (this.options.onToken)\n { this.options.onToken(new Token(this)); }\n\n this.lastTokEnd = this.end;\n this.lastTokStart = this.start;\n this.lastTokEndLoc = this.endLoc;\n this.lastTokStartLoc = this.startLoc;\n this.nextToken();\n};\n\npp.getToken = function() {\n this.next();\n return new Token(this)\n};\n\n// If we're in an ES6 environment, make parsers iterable\nif (typeof Symbol !== \"undefined\")\n { pp[Symbol.iterator] = function() {\n var this$1$1 = this;\n\n return {\n next: function () {\n var token = this$1$1.getToken();\n return {\n done: token.type === types$1.eof,\n value: token\n }\n }\n }\n }; }\n\n// Toggle strict mode. Re-reads the next number or string to please\n// pedantic tests (`\"use strict\"; 010;` should fail).\n\n// Read a single token, updating the parser object's token-related\n// properties.\n\npp.nextToken = function() {\n var curContext = this.curContext();\n if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }\n\n this.start = this.pos;\n if (this.options.locations) { this.startLoc = this.curPosition(); }\n if (this.pos >= this.input.length) { return this.finishToken(types$1.eof) }\n\n if (curContext.override) { return curContext.override(this) }\n else { this.readToken(this.fullCharCodeAtPos()); }\n};\n\npp.readToken = function(code) {\n // Identifier or keyword. '\\uXXXX' sequences are allowed in\n // identifiers, so '\\' also dispatches to that.\n if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\\' */)\n { return this.readWord() }\n\n return this.getTokenFromCode(code)\n};\n\npp.fullCharCodeAtPos = function() {\n var code = this.input.charCodeAt(this.pos);\n if (code <= 0xd7ff || code >= 0xdc00) { return code }\n var next = this.input.charCodeAt(this.pos + 1);\n return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00\n};\n\npp.skipBlockComment = function() {\n var startLoc = this.options.onComment && this.curPosition();\n var start = this.pos, end = this.input.indexOf(\"*/\", this.pos += 2);\n if (end === -1) { this.raise(this.pos - 2, \"Unterminated comment\"); }\n this.pos = end + 2;\n if (this.options.locations) {\n for (var nextBreak = (void 0), pos = start; (nextBreak = nextLineBreak(this.input, pos, this.pos)) > -1;) {\n ++this.curLine;\n pos = this.lineStart = nextBreak;\n }\n }\n if (this.options.onComment)\n { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,\n startLoc, this.curPosition()); }\n};\n\npp.skipLineComment = function(startSkip) {\n var start = this.pos;\n var startLoc = this.options.onComment && this.curPosition();\n var ch = this.input.charCodeAt(this.pos += startSkip);\n while (this.pos < this.input.length && !isNewLine(ch)) {\n ch = this.input.charCodeAt(++this.pos);\n }\n if (this.options.onComment)\n { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,\n startLoc, this.curPosition()); }\n};\n\n// Called at the start of the parse and after every token. Skips\n// whitespace and comments, and.\n\npp.skipSpace = function() {\n loop: while (this.pos < this.input.length) {\n var ch = this.input.charCodeAt(this.pos);\n switch (ch) {\n case 32: case 160: // ' '\n ++this.pos;\n break\n case 13:\n if (this.input.charCodeAt(this.pos + 1) === 10) {\n ++this.pos;\n }\n case 10: case 8232: case 8233:\n ++this.pos;\n if (this.options.locations) {\n ++this.curLine;\n this.lineStart = this.pos;\n }\n break\n case 47: // '/'\n switch (this.input.charCodeAt(this.pos + 1)) {\n case 42: // '*'\n this.skipBlockComment();\n break\n case 47:\n this.skipLineComment(2);\n break\n default:\n break loop\n }\n break\n default:\n if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {\n ++this.pos;\n } else {\n break loop\n }\n }\n }\n};\n\n// Called at the end of every token. Sets `end`, `val`, and\n// maintains `context` and `exprAllowed`, and skips the space after\n// the token, so that the next one's `start` will point at the\n// right position.\n\npp.finishToken = function(type, val) {\n this.end = this.pos;\n if (this.options.locations) { this.endLoc = this.curPosition(); }\n var prevType = this.type;\n this.type = type;\n this.value = val;\n\n this.updateContext(prevType);\n};\n\n// ### Token reading\n\n// This is the function that is called to fetch the next token. It\n// is somewhat obscure, because it works in character codes rather\n// than characters, and because operator parsing has been inlined\n// into it.\n//\n// All in the name of speed.\n//\npp.readToken_dot = function() {\n var next = this.input.charCodeAt(this.pos + 1);\n if (next >= 48 && next <= 57) { return this.readNumber(true) }\n var next2 = this.input.charCodeAt(this.pos + 2);\n if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'\n this.pos += 3;\n return this.finishToken(types$1.ellipsis)\n } else {\n ++this.pos;\n return this.finishToken(types$1.dot)\n }\n};\n\npp.readToken_slash = function() { // '/'\n var next = this.input.charCodeAt(this.pos + 1);\n if (this.exprAllowed) { ++this.pos; return this.readRegexp() }\n if (next === 61) { return this.finishOp(types$1.assign, 2) }\n return this.finishOp(types$1.slash, 1)\n};\n\npp.readToken_mult_modulo_exp = function(code) { // '%*'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n var tokentype = code === 42 ? types$1.star : types$1.modulo;\n\n // exponentiation operator ** and **=\n if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {\n ++size;\n tokentype = types$1.starstar;\n next = this.input.charCodeAt(this.pos + 2);\n }\n\n if (next === 61) { return this.finishOp(types$1.assign, size + 1) }\n return this.finishOp(tokentype, size)\n};\n\npp.readToken_pipe_amp = function(code) { // '|&'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === code) {\n if (this.options.ecmaVersion >= 12) {\n var next2 = this.input.charCodeAt(this.pos + 2);\n if (next2 === 61) { return this.finishOp(types$1.assign, 3) }\n }\n return this.finishOp(code === 124 ? types$1.logicalOR : types$1.logicalAND, 2)\n }\n if (next === 61) { return this.finishOp(types$1.assign, 2) }\n return this.finishOp(code === 124 ? types$1.bitwiseOR : types$1.bitwiseAND, 1)\n};\n\npp.readToken_caret = function() { // '^'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === 61) { return this.finishOp(types$1.assign, 2) }\n return this.finishOp(types$1.bitwiseXOR, 1)\n};\n\npp.readToken_plus_min = function(code) { // '+-'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === code) {\n if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 &&\n (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {\n // A `-->` line comment\n this.skipLineComment(3);\n this.skipSpace();\n return this.nextToken()\n }\n return this.finishOp(types$1.incDec, 2)\n }\n if (next === 61) { return this.finishOp(types$1.assign, 2) }\n return this.finishOp(types$1.plusMin, 1)\n};\n\npp.readToken_lt_gt = function(code) { // '<>'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n if (next === code) {\n size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;\n if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) }\n return this.finishOp(types$1.bitShift, size)\n }\n if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&\n this.input.charCodeAt(this.pos + 3) === 45) {\n // `` line comment\n this.skipLineComment(3);\n this.skipSpace();\n return this.nextToken()\n }\n return this.finishOp(types$1.incDec, 2)\n }\n if (next === 61) { return this.finishOp(types$1.assign, 2) }\n return this.finishOp(types$1.plusMin, 1)\n };\n\n pp.readToken_lt_gt = function(code) { // '<>'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n if (next === code) {\n size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;\n if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) }\n return this.finishOp(types$1.bitShift, size)\n }\n if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&\n this.input.charCodeAt(this.pos + 3) === 45) {\n // `\\n\\n'\n }\n }\n\n return '\\n\\n'\n}\n","/**\n * @typedef {import('../types.js').IndentLines} IndentLines\n */\n\nconst eol = /\\r?\\n|\\r/g\n\n/**\n * @type {IndentLines}\n */\nexport function indentLines(value, map) {\n /** @type {Array} */\n const result = []\n let start = 0\n let line = 0\n /** @type {RegExpExecArray | null} */\n let match\n\n while ((match = eol.exec(value))) {\n one(value.slice(start, match.index))\n result.push(match[0])\n start = match.index + match[0].length\n line++\n }\n\n one(value.slice(start))\n\n return result.join('')\n\n /**\n * @param {string} value\n */\n function one(value) {\n result.push(map(value, line, !value))\n }\n}\n","/**\n * @typedef {import('../types.js').State} State\n * @typedef {import('../types.js').SafeConfig} SafeConfig\n */\n\nimport {patternCompile} from './pattern-compile.js'\nimport {patternInScope} from './pattern-in-scope.js'\n\n/**\n * Make a string safe for embedding in markdown constructs.\n *\n * In markdown, almost all punctuation characters can, in certain cases,\n * result in something.\n * Whether they do is highly subjective to where they happen and in what\n * they happen.\n *\n * To solve this, `mdast-util-to-markdown` tracks:\n *\n * * Characters before and after something;\n * * What “constructs” we are in.\n *\n * This information is then used by this function to escape or encode\n * special characters.\n *\n * @param {State} state\n * Info passed around about the current state.\n * @param {string | null | undefined} input\n * Raw value to make safe.\n * @param {SafeConfig} config\n * Configuration.\n * @returns {string}\n * Serialized markdown safe for embedding.\n */\nexport function safe(state, input, config) {\n const value = (config.before || '') + (input || '') + (config.after || '')\n /** @type {Array} */\n const positions = []\n /** @type {Array} */\n const result = []\n /** @type {Record} */\n const infos = {}\n let index = -1\n\n while (++index < state.unsafe.length) {\n const pattern = state.unsafe[index]\n\n if (!patternInScope(state.stack, pattern)) {\n continue\n }\n\n const expression = patternCompile(pattern)\n /** @type {RegExpExecArray | null} */\n let match\n\n while ((match = expression.exec(value))) {\n const before = 'before' in pattern || Boolean(pattern.atBreak)\n const after = 'after' in pattern\n const position = match.index + (before ? match[1].length : 0)\n\n if (positions.includes(position)) {\n if (infos[position].before && !before) {\n infos[position].before = false\n }\n\n if (infos[position].after && !after) {\n infos[position].after = false\n }\n } else {\n positions.push(position)\n infos[position] = {before, after}\n }\n }\n }\n\n positions.sort(numerical)\n\n let start = config.before ? config.before.length : 0\n const end = value.length - (config.after ? config.after.length : 0)\n index = -1\n\n while (++index < positions.length) {\n const position = positions[index]\n\n // Character before or after matched:\n if (position < start || position >= end) {\n continue\n }\n\n // If this character is supposed to be escaped because it has a condition on\n // the next character, and the next character is definitly being escaped,\n // then skip this escape.\n if (\n (position + 1 < end &&\n positions[index + 1] === position + 1 &&\n infos[position].after &&\n !infos[position + 1].before &&\n !infos[position + 1].after) ||\n (positions[index - 1] === position - 1 &&\n infos[position].before &&\n !infos[position - 1].before &&\n !infos[position - 1].after)\n ) {\n continue\n }\n\n if (start !== position) {\n // If we have to use a character reference, an ampersand would be more\n // correct, but as backslashes only care about punctuation, either will\n // do the trick\n result.push(escapeBackslashes(value.slice(start, position), '\\\\'))\n }\n\n start = position\n\n if (\n /[!-/:-@[-`{-~]/.test(value.charAt(position)) &&\n (!config.encode || !config.encode.includes(value.charAt(position)))\n ) {\n // Character escape.\n result.push('\\\\')\n } else {\n // Character reference.\n result.push(\n '&#x' + value.charCodeAt(position).toString(16).toUpperCase() + ';'\n )\n start++\n }\n }\n\n result.push(escapeBackslashes(value.slice(start, end), config.after))\n\n return result.join('')\n}\n\n/**\n * @param {number} a\n * @param {number} b\n * @returns {number}\n */\nfunction numerical(a, b) {\n return a - b\n}\n\n/**\n * @param {string} value\n * @param {string} after\n * @returns {string}\n */\nfunction escapeBackslashes(value, after) {\n const expression = /\\\\(?=[!-/:-@[-`{-~])/g\n /** @type {Array} */\n const positions = []\n /** @type {Array} */\n const results = []\n const whole = value + after\n let index = -1\n let start = 0\n /** @type {RegExpExecArray | null} */\n let match\n\n while ((match = expression.exec(whole))) {\n positions.push(match.index)\n }\n\n while (++index < positions.length) {\n if (start !== positions[index]) {\n results.push(value.slice(start, positions[index]))\n }\n\n results.push('\\\\')\n start = positions[index]\n }\n\n results.push(value.slice(start))\n\n return results.join('')\n}\n","/**\n * @typedef {import('../types.js').CreateTracker} CreateTracker\n * @typedef {import('../types.js').TrackCurrent} TrackCurrent\n * @typedef {import('../types.js').TrackMove} TrackMove\n * @typedef {import('../types.js').TrackShift} TrackShift\n */\n\n/**\n * Track positional info in the output.\n *\n * @type {CreateTracker}\n */\nexport function track(config) {\n // Defaults are used to prevent crashes when older utilities somehow activate\n // this code.\n /* c8 ignore next 5 */\n const options = config || {}\n const now = options.now || {}\n let lineShift = options.lineShift || 0\n let line = now.line || 1\n let column = now.column || 1\n\n return {move, current, shift}\n\n /**\n * Get the current tracked info.\n *\n * @type {TrackCurrent}\n */\n function current() {\n return {now: {line, column}, lineShift}\n }\n\n /**\n * Define an increased line shift (the typical indent for lines).\n *\n * @type {TrackShift}\n */\n function shift(value) {\n lineShift += value\n }\n\n /**\n * Move past some generated markdown.\n *\n * @type {TrackMove}\n */\n function move(input) {\n // eslint-disable-next-line unicorn/prefer-default-parameters\n const value = input || ''\n const chunks = value.split(/\\r?\\n|\\r/g)\n const tail = chunks[chunks.length - 1]\n line += chunks.length - 1\n column =\n chunks.length === 1 ? column + tail.length : 1 + tail.length + lineShift\n return value\n }\n}\n","/**\n * @typedef {import('./types.js').Enter} Enter\n * @typedef {import('./types.js').Info} Info\n * @typedef {import('./types.js').Join} Join\n * @typedef {import('./types.js').FlowContent} FlowContent\n * @typedef {import('./types.js').Node} Node\n * @typedef {import('./types.js').Options} Options\n * @typedef {import('./types.js').Parent} Parent\n * @typedef {import('./types.js').PhrasingContent} PhrasingContent\n * @typedef {import('./types.js').SafeConfig} SafeConfig\n * @typedef {import('./types.js').State} State\n * @typedef {import('./types.js').TrackFields} TrackFields\n */\n\nimport {zwitch} from 'zwitch'\nimport {configure} from './configure.js'\nimport {handle as handlers} from './handle/index.js'\nimport {join} from './join.js'\nimport {unsafe} from './unsafe.js'\nimport {association} from './util/association.js'\nimport {containerPhrasing} from './util/container-phrasing.js'\nimport {containerFlow} from './util/container-flow.js'\nimport {indentLines} from './util/indent-lines.js'\nimport {safe} from './util/safe.js'\nimport {track} from './util/track.js'\n\n/**\n * Turn an mdast syntax tree into markdown.\n *\n * @param {Node} tree\n * Tree to serialize.\n * @param {Options} [options]\n * Configuration (optional).\n * @returns {string}\n * Serialized markdown representing `tree`.\n */\nexport function toMarkdown(tree, options = {}) {\n /** @type {State} */\n const state = {\n enter,\n indentLines,\n associationId: association,\n containerPhrasing: containerPhrasingBound,\n containerFlow: containerFlowBound,\n createTracker: track,\n safe: safeBound,\n stack: [],\n unsafe: [],\n join: [],\n // @ts-expect-error: we’ll fill it next.\n handlers: {},\n options: {},\n indexStack: [],\n // @ts-expect-error: we’ll add `handle` later.\n handle: undefined\n }\n\n configure(state, {unsafe, join, handlers})\n configure(state, options)\n\n if (state.options.tightDefinitions) {\n configure(state, {join: [joinDefinition]})\n }\n\n state.handle = zwitch('type', {\n invalid,\n unknown,\n handlers: state.handlers\n })\n\n let result = state.handle(tree, undefined, state, {\n before: '\\n',\n after: '\\n',\n now: {line: 1, column: 1},\n lineShift: 0\n })\n\n if (\n result &&\n result.charCodeAt(result.length - 1) !== 10 &&\n result.charCodeAt(result.length - 1) !== 13\n ) {\n result += '\\n'\n }\n\n return result\n\n /** @type {Enter} */\n function enter(name) {\n state.stack.push(name)\n return exit\n\n function exit() {\n state.stack.pop()\n }\n }\n}\n\n/**\n * @param {unknown} value\n * @returns {never}\n */\nfunction invalid(value) {\n throw new Error('Cannot handle value `' + value + '`, expected node')\n}\n\n/**\n * @param {unknown} node\n * @returns {never}\n */\nfunction unknown(node) {\n // @ts-expect-error: fine.\n throw new Error('Cannot handle unknown node `' + node.type + '`')\n}\n\n/** @type {Join} */\nfunction joinDefinition(left, right) {\n // No blank line between adjacent definitions.\n if (left.type === 'definition' && left.type === right.type) {\n return 0\n }\n}\n\n/**\n * Serialize the children of a parent that contains phrasing children.\n *\n * These children will be joined flush together.\n *\n * @this {State}\n * Info passed around about the current state.\n * @param {Parent & {children: Array}} parent\n * Parent of flow nodes.\n * @param {Info} info\n * Info on where we are in the document we are generating.\n * @returns {string}\n * Serialized children, joined together.\n */\nfunction containerPhrasingBound(parent, info) {\n return containerPhrasing(parent, this, info)\n}\n\n/**\n * Serialize the children of a parent that contains flow children.\n *\n * These children will typically be joined by blank lines.\n * What they are joined by exactly is defined by `Join` functions.\n *\n * @this {State}\n * Info passed around about the current state.\n * @param {Parent & {children: Array}} parent\n * Parent of flow nodes.\n * @param {TrackFields} info\n * Info on where we are in the document we are generating.\n * @returns {string}\n * Serialized children, joined by (blank) lines.\n */\nfunction containerFlowBound(parent, info) {\n return containerFlow(parent, this, info)\n}\n\n/**\n * Make a string safe for embedding in markdown constructs.\n *\n * In markdown, almost all punctuation characters can, in certain cases,\n * result in something.\n * Whether they do is highly subjective to where they happen and in what\n * they happen.\n *\n * To solve this, `mdast-util-to-markdown` tracks:\n *\n * * Characters before and after something;\n * * What “constructs” we are in.\n *\n * This information is then used by this function to escape or encode\n * special characters.\n *\n * @this {State}\n * Info passed around about the current state.\n * @param {string | null | undefined} value\n * Raw value to make safe.\n * @param {SafeConfig} config\n * Configuration.\n * @returns {string}\n * Serialized markdown safe for embedding.\n */\nfunction safeBound(value, config) {\n return safe(this, value, config)\n}\n","// This file was generated. Do not modify manually!\nvar astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 81, 2, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 9, 5351, 0, 7, 14, 13835, 9, 87, 9, 39, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4706, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 983, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];\n\n// This file was generated. Do not modify manually!\nvar astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 68, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 4026, 582, 8634, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8936, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 757, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4153, 7, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938, 6, 4191];\n\n// This file was generated. Do not modify manually!\nvar nonASCIIidentifierChars = \"\\u200c\\u200d\\xb7\\u0300-\\u036f\\u0387\\u0483-\\u0487\\u0591-\\u05bd\\u05bf\\u05c1\\u05c2\\u05c4\\u05c5\\u05c7\\u0610-\\u061a\\u064b-\\u0669\\u0670\\u06d6-\\u06dc\\u06df-\\u06e4\\u06e7\\u06e8\\u06ea-\\u06ed\\u06f0-\\u06f9\\u0711\\u0730-\\u074a\\u07a6-\\u07b0\\u07c0-\\u07c9\\u07eb-\\u07f3\\u07fd\\u0816-\\u0819\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0859-\\u085b\\u0898-\\u089f\\u08ca-\\u08e1\\u08e3-\\u0903\\u093a-\\u093c\\u093e-\\u094f\\u0951-\\u0957\\u0962\\u0963\\u0966-\\u096f\\u0981-\\u0983\\u09bc\\u09be-\\u09c4\\u09c7\\u09c8\\u09cb-\\u09cd\\u09d7\\u09e2\\u09e3\\u09e6-\\u09ef\\u09fe\\u0a01-\\u0a03\\u0a3c\\u0a3e-\\u0a42\\u0a47\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a66-\\u0a71\\u0a75\\u0a81-\\u0a83\\u0abc\\u0abe-\\u0ac5\\u0ac7-\\u0ac9\\u0acb-\\u0acd\\u0ae2\\u0ae3\\u0ae6-\\u0aef\\u0afa-\\u0aff\\u0b01-\\u0b03\\u0b3c\\u0b3e-\\u0b44\\u0b47\\u0b48\\u0b4b-\\u0b4d\\u0b55-\\u0b57\\u0b62\\u0b63\\u0b66-\\u0b6f\\u0b82\\u0bbe-\\u0bc2\\u0bc6-\\u0bc8\\u0bca-\\u0bcd\\u0bd7\\u0be6-\\u0bef\\u0c00-\\u0c04\\u0c3c\\u0c3e-\\u0c44\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55\\u0c56\\u0c62\\u0c63\\u0c66-\\u0c6f\\u0c81-\\u0c83\\u0cbc\\u0cbe-\\u0cc4\\u0cc6-\\u0cc8\\u0cca-\\u0ccd\\u0cd5\\u0cd6\\u0ce2\\u0ce3\\u0ce6-\\u0cef\\u0cf3\\u0d00-\\u0d03\\u0d3b\\u0d3c\\u0d3e-\\u0d44\\u0d46-\\u0d48\\u0d4a-\\u0d4d\\u0d57\\u0d62\\u0d63\\u0d66-\\u0d6f\\u0d81-\\u0d83\\u0dca\\u0dcf-\\u0dd4\\u0dd6\\u0dd8-\\u0ddf\\u0de6-\\u0def\\u0df2\\u0df3\\u0e31\\u0e34-\\u0e3a\\u0e47-\\u0e4e\\u0e50-\\u0e59\\u0eb1\\u0eb4-\\u0ebc\\u0ec8-\\u0ece\\u0ed0-\\u0ed9\\u0f18\\u0f19\\u0f20-\\u0f29\\u0f35\\u0f37\\u0f39\\u0f3e\\u0f3f\\u0f71-\\u0f84\\u0f86\\u0f87\\u0f8d-\\u0f97\\u0f99-\\u0fbc\\u0fc6\\u102b-\\u103e\\u1040-\\u1049\\u1056-\\u1059\\u105e-\\u1060\\u1062-\\u1064\\u1067-\\u106d\\u1071-\\u1074\\u1082-\\u108d\\u108f-\\u109d\\u135d-\\u135f\\u1369-\\u1371\\u1712-\\u1715\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17b4-\\u17d3\\u17dd\\u17e0-\\u17e9\\u180b-\\u180d\\u180f-\\u1819\\u18a9\\u1920-\\u192b\\u1930-\\u193b\\u1946-\\u194f\\u19d0-\\u19da\\u1a17-\\u1a1b\\u1a55-\\u1a5e\\u1a60-\\u1a7c\\u1a7f-\\u1a89\\u1a90-\\u1a99\\u1ab0-\\u1abd\\u1abf-\\u1ace\\u1b00-\\u1b04\\u1b34-\\u1b44\\u1b50-\\u1b59\\u1b6b-\\u1b73\\u1b80-\\u1b82\\u1ba1-\\u1bad\\u1bb0-\\u1bb9\\u1be6-\\u1bf3\\u1c24-\\u1c37\\u1c40-\\u1c49\\u1c50-\\u1c59\\u1cd0-\\u1cd2\\u1cd4-\\u1ce8\\u1ced\\u1cf4\\u1cf7-\\u1cf9\\u1dc0-\\u1dff\\u203f\\u2040\\u2054\\u20d0-\\u20dc\\u20e1\\u20e5-\\u20f0\\u2cef-\\u2cf1\\u2d7f\\u2de0-\\u2dff\\u302a-\\u302f\\u3099\\u309a\\ua620-\\ua629\\ua66f\\ua674-\\ua67d\\ua69e\\ua69f\\ua6f0\\ua6f1\\ua802\\ua806\\ua80b\\ua823-\\ua827\\ua82c\\ua880\\ua881\\ua8b4-\\ua8c5\\ua8d0-\\ua8d9\\ua8e0-\\ua8f1\\ua8ff-\\ua909\\ua926-\\ua92d\\ua947-\\ua953\\ua980-\\ua983\\ua9b3-\\ua9c0\\ua9d0-\\ua9d9\\ua9e5\\ua9f0-\\ua9f9\\uaa29-\\uaa36\\uaa43\\uaa4c\\uaa4d\\uaa50-\\uaa59\\uaa7b-\\uaa7d\\uaab0\\uaab2-\\uaab4\\uaab7\\uaab8\\uaabe\\uaabf\\uaac1\\uaaeb-\\uaaef\\uaaf5\\uaaf6\\uabe3-\\uabea\\uabec\\uabed\\uabf0-\\uabf9\\ufb1e\\ufe00-\\ufe0f\\ufe20-\\ufe2f\\ufe33\\ufe34\\ufe4d-\\ufe4f\\uff10-\\uff19\\uff3f\";\n\n// This file was generated. Do not modify manually!\nvar nonASCIIidentifierStartChars = \"\\xaa\\xb5\\xba\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\u02c1\\u02c6-\\u02d1\\u02e0-\\u02e4\\u02ec\\u02ee\\u0370-\\u0374\\u0376\\u0377\\u037a-\\u037d\\u037f\\u0386\\u0388-\\u038a\\u038c\\u038e-\\u03a1\\u03a3-\\u03f5\\u03f7-\\u0481\\u048a-\\u052f\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05d0-\\u05ea\\u05ef-\\u05f2\\u0620-\\u064a\\u066e\\u066f\\u0671-\\u06d3\\u06d5\\u06e5\\u06e6\\u06ee\\u06ef\\u06fa-\\u06fc\\u06ff\\u0710\\u0712-\\u072f\\u074d-\\u07a5\\u07b1\\u07ca-\\u07ea\\u07f4\\u07f5\\u07fa\\u0800-\\u0815\\u081a\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086a\\u0870-\\u0887\\u0889-\\u088e\\u08a0-\\u08c9\\u0904-\\u0939\\u093d\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098c\\u098f\\u0990\\u0993-\\u09a8\\u09aa-\\u09b0\\u09b2\\u09b6-\\u09b9\\u09bd\\u09ce\\u09dc\\u09dd\\u09df-\\u09e1\\u09f0\\u09f1\\u09fc\\u0a05-\\u0a0a\\u0a0f\\u0a10\\u0a13-\\u0a28\\u0a2a-\\u0a30\\u0a32\\u0a33\\u0a35\\u0a36\\u0a38\\u0a39\\u0a59-\\u0a5c\\u0a5e\\u0a72-\\u0a74\\u0a85-\\u0a8d\\u0a8f-\\u0a91\\u0a93-\\u0aa8\\u0aaa-\\u0ab0\\u0ab2\\u0ab3\\u0ab5-\\u0ab9\\u0abd\\u0ad0\\u0ae0\\u0ae1\\u0af9\\u0b05-\\u0b0c\\u0b0f\\u0b10\\u0b13-\\u0b28\\u0b2a-\\u0b30\\u0b32\\u0b33\\u0b35-\\u0b39\\u0b3d\\u0b5c\\u0b5d\\u0b5f-\\u0b61\\u0b71\\u0b83\\u0b85-\\u0b8a\\u0b8e-\\u0b90\\u0b92-\\u0b95\\u0b99\\u0b9a\\u0b9c\\u0b9e\\u0b9f\\u0ba3\\u0ba4\\u0ba8-\\u0baa\\u0bae-\\u0bb9\\u0bd0\\u0c05-\\u0c0c\\u0c0e-\\u0c10\\u0c12-\\u0c28\\u0c2a-\\u0c39\\u0c3d\\u0c58-\\u0c5a\\u0c5d\\u0c60\\u0c61\\u0c80\\u0c85-\\u0c8c\\u0c8e-\\u0c90\\u0c92-\\u0ca8\\u0caa-\\u0cb3\\u0cb5-\\u0cb9\\u0cbd\\u0cdd\\u0cde\\u0ce0\\u0ce1\\u0cf1\\u0cf2\\u0d04-\\u0d0c\\u0d0e-\\u0d10\\u0d12-\\u0d3a\\u0d3d\\u0d4e\\u0d54-\\u0d56\\u0d5f-\\u0d61\\u0d7a-\\u0d7f\\u0d85-\\u0d96\\u0d9a-\\u0db1\\u0db3-\\u0dbb\\u0dbd\\u0dc0-\\u0dc6\\u0e01-\\u0e30\\u0e32\\u0e33\\u0e40-\\u0e46\\u0e81\\u0e82\\u0e84\\u0e86-\\u0e8a\\u0e8c-\\u0ea3\\u0ea5\\u0ea7-\\u0eb0\\u0eb2\\u0eb3\\u0ebd\\u0ec0-\\u0ec4\\u0ec6\\u0edc-\\u0edf\\u0f00\\u0f40-\\u0f47\\u0f49-\\u0f6c\\u0f88-\\u0f8c\\u1000-\\u102a\\u103f\\u1050-\\u1055\\u105a-\\u105d\\u1061\\u1065\\u1066\\u106e-\\u1070\\u1075-\\u1081\\u108e\\u10a0-\\u10c5\\u10c7\\u10cd\\u10d0-\\u10fa\\u10fc-\\u1248\\u124a-\\u124d\\u1250-\\u1256\\u1258\\u125a-\\u125d\\u1260-\\u1288\\u128a-\\u128d\\u1290-\\u12b0\\u12b2-\\u12b5\\u12b8-\\u12be\\u12c0\\u12c2-\\u12c5\\u12c8-\\u12d6\\u12d8-\\u1310\\u1312-\\u1315\\u1318-\\u135a\\u1380-\\u138f\\u13a0-\\u13f5\\u13f8-\\u13fd\\u1401-\\u166c\\u166f-\\u167f\\u1681-\\u169a\\u16a0-\\u16ea\\u16ee-\\u16f8\\u1700-\\u1711\\u171f-\\u1731\\u1740-\\u1751\\u1760-\\u176c\\u176e-\\u1770\\u1780-\\u17b3\\u17d7\\u17dc\\u1820-\\u1878\\u1880-\\u18a8\\u18aa\\u18b0-\\u18f5\\u1900-\\u191e\\u1950-\\u196d\\u1970-\\u1974\\u1980-\\u19ab\\u19b0-\\u19c9\\u1a00-\\u1a16\\u1a20-\\u1a54\\u1aa7\\u1b05-\\u1b33\\u1b45-\\u1b4c\\u1b83-\\u1ba0\\u1bae\\u1baf\\u1bba-\\u1be5\\u1c00-\\u1c23\\u1c4d-\\u1c4f\\u1c5a-\\u1c7d\\u1c80-\\u1c88\\u1c90-\\u1cba\\u1cbd-\\u1cbf\\u1ce9-\\u1cec\\u1cee-\\u1cf3\\u1cf5\\u1cf6\\u1cfa\\u1d00-\\u1dbf\\u1e00-\\u1f15\\u1f18-\\u1f1d\\u1f20-\\u1f45\\u1f48-\\u1f4d\\u1f50-\\u1f57\\u1f59\\u1f5b\\u1f5d\\u1f5f-\\u1f7d\\u1f80-\\u1fb4\\u1fb6-\\u1fbc\\u1fbe\\u1fc2-\\u1fc4\\u1fc6-\\u1fcc\\u1fd0-\\u1fd3\\u1fd6-\\u1fdb\\u1fe0-\\u1fec\\u1ff2-\\u1ff4\\u1ff6-\\u1ffc\\u2071\\u207f\\u2090-\\u209c\\u2102\\u2107\\u210a-\\u2113\\u2115\\u2118-\\u211d\\u2124\\u2126\\u2128\\u212a-\\u2139\\u213c-\\u213f\\u2145-\\u2149\\u214e\\u2160-\\u2188\\u2c00-\\u2ce4\\u2ceb-\\u2cee\\u2cf2\\u2cf3\\u2d00-\\u2d25\\u2d27\\u2d2d\\u2d30-\\u2d67\\u2d6f\\u2d80-\\u2d96\\u2da0-\\u2da6\\u2da8-\\u2dae\\u2db0-\\u2db6\\u2db8-\\u2dbe\\u2dc0-\\u2dc6\\u2dc8-\\u2dce\\u2dd0-\\u2dd6\\u2dd8-\\u2dde\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303c\\u3041-\\u3096\\u309b-\\u309f\\u30a1-\\u30fa\\u30fc-\\u30ff\\u3105-\\u312f\\u3131-\\u318e\\u31a0-\\u31bf\\u31f0-\\u31ff\\u3400-\\u4dbf\\u4e00-\\ua48c\\ua4d0-\\ua4fd\\ua500-\\ua60c\\ua610-\\ua61f\\ua62a\\ua62b\\ua640-\\ua66e\\ua67f-\\ua69d\\ua6a0-\\ua6ef\\ua717-\\ua71f\\ua722-\\ua788\\ua78b-\\ua7ca\\ua7d0\\ua7d1\\ua7d3\\ua7d5-\\ua7d9\\ua7f2-\\ua801\\ua803-\\ua805\\ua807-\\ua80a\\ua80c-\\ua822\\ua840-\\ua873\\ua882-\\ua8b3\\ua8f2-\\ua8f7\\ua8fb\\ua8fd\\ua8fe\\ua90a-\\ua925\\ua930-\\ua946\\ua960-\\ua97c\\ua984-\\ua9b2\\ua9cf\\ua9e0-\\ua9e4\\ua9e6-\\ua9ef\\ua9fa-\\ua9fe\\uaa00-\\uaa28\\uaa40-\\uaa42\\uaa44-\\uaa4b\\uaa60-\\uaa76\\uaa7a\\uaa7e-\\uaaaf\\uaab1\\uaab5\\uaab6\\uaab9-\\uaabd\\uaac0\\uaac2\\uaadb-\\uaadd\\uaae0-\\uaaea\\uaaf2-\\uaaf4\\uab01-\\uab06\\uab09-\\uab0e\\uab11-\\uab16\\uab20-\\uab26\\uab28-\\uab2e\\uab30-\\uab5a\\uab5c-\\uab69\\uab70-\\uabe2\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\uf900-\\ufa6d\\ufa70-\\ufad9\\ufb00-\\ufb06\\ufb13-\\ufb17\\ufb1d\\ufb1f-\\ufb28\\ufb2a-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40\\ufb41\\ufb43\\ufb44\\ufb46-\\ufbb1\\ufbd3-\\ufd3d\\ufd50-\\ufd8f\\ufd92-\\ufdc7\\ufdf0-\\ufdfb\\ufe70-\\ufe74\\ufe76-\\ufefc\\uff21-\\uff3a\\uff41-\\uff5a\\uff66-\\uffbe\\uffc2-\\uffc7\\uffca-\\uffcf\\uffd2-\\uffd7\\uffda-\\uffdc\";\n\n// These are a run-length and offset encoded representation of the\n\n// Reserved word lists for various dialects of the language\n\nvar reservedWords = {\n 3: \"abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile\",\n 5: \"class enum extends super const export import\",\n 6: \"enum\",\n strict: \"implements interface let package private protected public static yield\",\n strictBind: \"eval arguments\"\n};\n\n// And the keywords\n\nvar ecma5AndLessKeywords = \"break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this\";\n\nvar keywords$1 = {\n 5: ecma5AndLessKeywords,\n \"5module\": ecma5AndLessKeywords + \" export import\",\n 6: ecma5AndLessKeywords + \" const class extends export import super\"\n};\n\nvar keywordRelationalOperator = /^in(stanceof)?$/;\n\n// ## Character categories\n\nvar nonASCIIidentifierStart = new RegExp(\"[\" + nonASCIIidentifierStartChars + \"]\");\nvar nonASCIIidentifier = new RegExp(\"[\" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + \"]\");\n\n// This has a complexity linear to the value of the code. The\n// assumption is that looking up astral identifier characters is\n// rare.\nfunction isInAstralSet(code, set) {\n var pos = 0x10000;\n for (var i = 0; i < set.length; i += 2) {\n pos += set[i];\n if (pos > code) { return false }\n pos += set[i + 1];\n if (pos >= code) { return true }\n }\n return false\n}\n\n// Test whether a given character code starts an identifier.\n\nfunction isIdentifierStart(code, astral) {\n if (code < 65) { return code === 36 }\n if (code < 91) { return true }\n if (code < 97) { return code === 95 }\n if (code < 123) { return true }\n if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }\n if (astral === false) { return false }\n return isInAstralSet(code, astralIdentifierStartCodes)\n}\n\n// Test whether a given character is part of an identifier.\n\nfunction isIdentifierChar(code, astral) {\n if (code < 48) { return code === 36 }\n if (code < 58) { return true }\n if (code < 65) { return false }\n if (code < 91) { return true }\n if (code < 97) { return code === 95 }\n if (code < 123) { return true }\n if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }\n if (astral === false) { return false }\n return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)\n}\n\n// ## Token types\n\n// The assignment of fine-grained, information-carrying type objects\n// allows the tokenizer to store the information it has about a\n// token in a way that is very cheap for the parser to look up.\n\n// All token type variables start with an underscore, to make them\n// easy to recognize.\n\n// The `beforeExpr` property is used to disambiguate between regular\n// expressions and divisions. It is set on all token types that can\n// be followed by an expression (thus, a slash after them would be a\n// regular expression).\n//\n// The `startsExpr` property is used to check if the token ends a\n// `yield` expression. It is set on all token types that either can\n// directly start an expression (like a quotation mark) or can\n// continue an expression (like the body of a string).\n//\n// `isLoop` marks a keyword as starting a loop, which is important\n// to know when parsing a label, in order to allow or disallow\n// continue jumps to that label.\n\nvar TokenType = function TokenType(label, conf) {\n if ( conf === void 0 ) conf = {};\n\n this.label = label;\n this.keyword = conf.keyword;\n this.beforeExpr = !!conf.beforeExpr;\n this.startsExpr = !!conf.startsExpr;\n this.isLoop = !!conf.isLoop;\n this.isAssign = !!conf.isAssign;\n this.prefix = !!conf.prefix;\n this.postfix = !!conf.postfix;\n this.binop = conf.binop || null;\n this.updateContext = null;\n};\n\nfunction binop(name, prec) {\n return new TokenType(name, {beforeExpr: true, binop: prec})\n}\nvar beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true};\n\n// Map keyword names to token types.\n\nvar keywords = {};\n\n// Succinct definitions of keyword token types\nfunction kw(name, options) {\n if ( options === void 0 ) options = {};\n\n options.keyword = name;\n return keywords[name] = new TokenType(name, options)\n}\n\nvar types$1 = {\n num: new TokenType(\"num\", startsExpr),\n regexp: new TokenType(\"regexp\", startsExpr),\n string: new TokenType(\"string\", startsExpr),\n name: new TokenType(\"name\", startsExpr),\n privateId: new TokenType(\"privateId\", startsExpr),\n eof: new TokenType(\"eof\"),\n\n // Punctuation token types.\n bracketL: new TokenType(\"[\", {beforeExpr: true, startsExpr: true}),\n bracketR: new TokenType(\"]\"),\n braceL: new TokenType(\"{\", {beforeExpr: true, startsExpr: true}),\n braceR: new TokenType(\"}\"),\n parenL: new TokenType(\"(\", {beforeExpr: true, startsExpr: true}),\n parenR: new TokenType(\")\"),\n comma: new TokenType(\",\", beforeExpr),\n semi: new TokenType(\";\", beforeExpr),\n colon: new TokenType(\":\", beforeExpr),\n dot: new TokenType(\".\"),\n question: new TokenType(\"?\", beforeExpr),\n questionDot: new TokenType(\"?.\"),\n arrow: new TokenType(\"=>\", beforeExpr),\n template: new TokenType(\"template\"),\n invalidTemplate: new TokenType(\"invalidTemplate\"),\n ellipsis: new TokenType(\"...\", beforeExpr),\n backQuote: new TokenType(\"`\", startsExpr),\n dollarBraceL: new TokenType(\"${\", {beforeExpr: true, startsExpr: true}),\n\n // Operators. These carry several kinds of properties to help the\n // parser use them properly (the presence of these properties is\n // what categorizes them as operators).\n //\n // `binop`, when present, specifies that this operator is a binary\n // operator, and will refer to its precedence.\n //\n // `prefix` and `postfix` mark the operator as a prefix or postfix\n // unary operator.\n //\n // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as\n // binary operators with a very low precedence, that should result\n // in AssignmentExpression nodes.\n\n eq: new TokenType(\"=\", {beforeExpr: true, isAssign: true}),\n assign: new TokenType(\"_=\", {beforeExpr: true, isAssign: true}),\n incDec: new TokenType(\"++/--\", {prefix: true, postfix: true, startsExpr: true}),\n prefix: new TokenType(\"!/~\", {beforeExpr: true, prefix: true, startsExpr: true}),\n logicalOR: binop(\"||\", 1),\n logicalAND: binop(\"&&\", 2),\n bitwiseOR: binop(\"|\", 3),\n bitwiseXOR: binop(\"^\", 4),\n bitwiseAND: binop(\"&\", 5),\n equality: binop(\"==/!=/===/!==\", 6),\n relational: binop(\"/<=/>=\", 7),\n bitShift: binop(\"<>/>>>\", 8),\n plusMin: new TokenType(\"+/-\", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),\n modulo: binop(\"%\", 10),\n star: binop(\"*\", 10),\n slash: binop(\"/\", 10),\n starstar: new TokenType(\"**\", {beforeExpr: true}),\n coalesce: binop(\"??\", 1),\n\n // Keyword token types.\n _break: kw(\"break\"),\n _case: kw(\"case\", beforeExpr),\n _catch: kw(\"catch\"),\n _continue: kw(\"continue\"),\n _debugger: kw(\"debugger\"),\n _default: kw(\"default\", beforeExpr),\n _do: kw(\"do\", {isLoop: true, beforeExpr: true}),\n _else: kw(\"else\", beforeExpr),\n _finally: kw(\"finally\"),\n _for: kw(\"for\", {isLoop: true}),\n _function: kw(\"function\", startsExpr),\n _if: kw(\"if\"),\n _return: kw(\"return\", beforeExpr),\n _switch: kw(\"switch\"),\n _throw: kw(\"throw\", beforeExpr),\n _try: kw(\"try\"),\n _var: kw(\"var\"),\n _const: kw(\"const\"),\n _while: kw(\"while\", {isLoop: true}),\n _with: kw(\"with\"),\n _new: kw(\"new\", {beforeExpr: true, startsExpr: true}),\n _this: kw(\"this\", startsExpr),\n _super: kw(\"super\", startsExpr),\n _class: kw(\"class\", startsExpr),\n _extends: kw(\"extends\", beforeExpr),\n _export: kw(\"export\"),\n _import: kw(\"import\", startsExpr),\n _null: kw(\"null\", startsExpr),\n _true: kw(\"true\", startsExpr),\n _false: kw(\"false\", startsExpr),\n _in: kw(\"in\", {beforeExpr: true, binop: 7}),\n _instanceof: kw(\"instanceof\", {beforeExpr: true, binop: 7}),\n _typeof: kw(\"typeof\", {beforeExpr: true, prefix: true, startsExpr: true}),\n _void: kw(\"void\", {beforeExpr: true, prefix: true, startsExpr: true}),\n _delete: kw(\"delete\", {beforeExpr: true, prefix: true, startsExpr: true})\n};\n\n// Matches a whole line break (where CRLF is considered a single\n// line break). Used to count lines.\n\nvar lineBreak = /\\r\\n?|\\n|\\u2028|\\u2029/;\nvar lineBreakG = new RegExp(lineBreak.source, \"g\");\n\nfunction isNewLine(code) {\n return code === 10 || code === 13 || code === 0x2028 || code === 0x2029\n}\n\nfunction nextLineBreak(code, from, end) {\n if ( end === void 0 ) end = code.length;\n\n for (var i = from; i < end; i++) {\n var next = code.charCodeAt(i);\n if (isNewLine(next))\n { return i < end - 1 && next === 13 && code.charCodeAt(i + 1) === 10 ? i + 2 : i + 1 }\n }\n return -1\n}\n\nvar nonASCIIwhitespace = /[\\u1680\\u2000-\\u200a\\u202f\\u205f\\u3000\\ufeff]/;\n\nvar skipWhiteSpace = /(?:\\s|\\/\\/.*|\\/\\*[^]*?\\*\\/)*/g;\n\nvar ref = Object.prototype;\nvar hasOwnProperty = ref.hasOwnProperty;\nvar toString = ref.toString;\n\nvar hasOwn = Object.hasOwn || (function (obj, propName) { return (\n hasOwnProperty.call(obj, propName)\n); });\n\nvar isArray = Array.isArray || (function (obj) { return (\n toString.call(obj) === \"[object Array]\"\n); });\n\nfunction wordsRegexp(words) {\n return new RegExp(\"^(?:\" + words.replace(/ /g, \"|\") + \")$\")\n}\n\nfunction codePointToString(code) {\n // UTF-16 Decoding\n if (code <= 0xFFFF) { return String.fromCharCode(code) }\n code -= 0x10000;\n return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)\n}\n\nvar loneSurrogate = /(?:[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])/;\n\n// These are used when `options.locations` is on, for the\n// `startLoc` and `endLoc` properties.\n\nvar Position = function Position(line, col) {\n this.line = line;\n this.column = col;\n};\n\nPosition.prototype.offset = function offset (n) {\n return new Position(this.line, this.column + n)\n};\n\nvar SourceLocation = function SourceLocation(p, start, end) {\n this.start = start;\n this.end = end;\n if (p.sourceFile !== null) { this.source = p.sourceFile; }\n};\n\n// The `getLineInfo` function is mostly useful when the\n// `locations` option is off (for performance reasons) and you\n// want to find the line/column position for a given character\n// offset. `input` should be the code string that the offset refers\n// into.\n\nfunction getLineInfo(input, offset) {\n for (var line = 1, cur = 0;;) {\n var nextBreak = nextLineBreak(input, cur, offset);\n if (nextBreak < 0) { return new Position(line, offset - cur) }\n ++line;\n cur = nextBreak;\n }\n}\n\n// A second argument must be given to configure the parser process.\n// These options are recognized (only `ecmaVersion` is required):\n\nvar defaultOptions = {\n // `ecmaVersion` indicates the ECMAScript version to parse. Must be\n // either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10\n // (2019), 11 (2020), 12 (2021), 13 (2022), 14 (2023), or `\"latest\"`\n // (the latest version the library supports). This influences\n // support for strict mode, the set of reserved words, and support\n // for new syntax features.\n ecmaVersion: null,\n // `sourceType` indicates the mode the code should be parsed in.\n // Can be either `\"script\"` or `\"module\"`. This influences global\n // strict mode and parsing of `import` and `export` declarations.\n sourceType: \"script\",\n // `onInsertedSemicolon` can be a callback that will be called\n // when a semicolon is automatically inserted. It will be passed\n // the position of the comma as an offset, and if `locations` is\n // enabled, it is given the location as a `{line, column}` object\n // as second argument.\n onInsertedSemicolon: null,\n // `onTrailingComma` is similar to `onInsertedSemicolon`, but for\n // trailing commas.\n onTrailingComma: null,\n // By default, reserved words are only enforced if ecmaVersion >= 5.\n // Set `allowReserved` to a boolean value to explicitly turn this on\n // an off. When this option has the value \"never\", reserved words\n // and keywords can also not be used as property names.\n allowReserved: null,\n // When enabled, a return at the top level is not considered an\n // error.\n allowReturnOutsideFunction: false,\n // When enabled, import/export statements are not constrained to\n // appearing at the top of the program, and an import.meta expression\n // in a script isn't considered an error.\n allowImportExportEverywhere: false,\n // By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022.\n // When enabled, await identifiers are allowed to appear at the top-level scope,\n // but they are still not allowed in non-async functions.\n allowAwaitOutsideFunction: null,\n // When enabled, super identifiers are not constrained to\n // appearing in methods and do not raise an error when they appear elsewhere.\n allowSuperOutsideMethod: null,\n // When enabled, hashbang directive in the beginning of file is\n // allowed and treated as a line comment. Enabled by default when\n // `ecmaVersion` >= 2023.\n allowHashBang: false,\n // When `locations` is on, `loc` properties holding objects with\n // `start` and `end` properties in `{line, column}` form (with\n // line being 1-based and column 0-based) will be attached to the\n // nodes.\n locations: false,\n // A function can be passed as `onToken` option, which will\n // cause Acorn to call that function with object in the same\n // format as tokens returned from `tokenizer().getToken()`. Note\n // that you are not allowed to call the parser from the\n // callback—that will corrupt its internal state.\n onToken: null,\n // A function can be passed as `onComment` option, which will\n // cause Acorn to call that function with `(block, text, start,\n // end)` parameters whenever a comment is skipped. `block` is a\n // boolean indicating whether this is a block (`/* */`) comment,\n // `text` is the content of the comment, and `start` and `end` are\n // character offsets that denote the start and end of the comment.\n // When the `locations` option is on, two more parameters are\n // passed, the full `{line, column}` locations of the start and\n // end of the comments. Note that you are not allowed to call the\n // parser from the callback—that will corrupt its internal state.\n onComment: null,\n // Nodes have their start and end characters offsets recorded in\n // `start` and `end` properties (directly on the node, rather than\n // the `loc` object, which holds line/column data. To also add a\n // [semi-standardized][range] `range` property holding a `[start,\n // end]` array with the same numbers, set the `ranges` option to\n // `true`.\n //\n // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678\n ranges: false,\n // It is possible to parse multiple files into a single AST by\n // passing the tree produced by parsing the first file as\n // `program` option in subsequent parses. This will add the\n // toplevel forms of the parsed file to the `Program` (top) node\n // of an existing parse tree.\n program: null,\n // When `locations` is on, you can pass this to record the source\n // file in every node's `loc` object.\n sourceFile: null,\n // This value, if given, is stored in every node, whether\n // `locations` is on or off.\n directSourceFile: null,\n // When enabled, parenthesized expressions are represented by\n // (non-standard) ParenthesizedExpression nodes\n preserveParens: false\n};\n\n// Interpret and default an options object\n\nvar warnedAboutEcmaVersion = false;\n\nfunction getOptions(opts) {\n var options = {};\n\n for (var opt in defaultOptions)\n { options[opt] = opts && hasOwn(opts, opt) ? opts[opt] : defaultOptions[opt]; }\n\n if (options.ecmaVersion === \"latest\") {\n options.ecmaVersion = 1e8;\n } else if (options.ecmaVersion == null) {\n if (!warnedAboutEcmaVersion && typeof console === \"object\" && console.warn) {\n warnedAboutEcmaVersion = true;\n console.warn(\"Since Acorn 8.0.0, options.ecmaVersion is required.\\nDefaulting to 2020, but this will stop working in the future.\");\n }\n options.ecmaVersion = 11;\n } else if (options.ecmaVersion >= 2015) {\n options.ecmaVersion -= 2009;\n }\n\n if (options.allowReserved == null)\n { options.allowReserved = options.ecmaVersion < 5; }\n\n if (!opts || opts.allowHashBang == null)\n { options.allowHashBang = options.ecmaVersion >= 14; }\n\n if (isArray(options.onToken)) {\n var tokens = options.onToken;\n options.onToken = function (token) { return tokens.push(token); };\n }\n if (isArray(options.onComment))\n { options.onComment = pushComment(options, options.onComment); }\n\n return options\n}\n\nfunction pushComment(options, array) {\n return function(block, text, start, end, startLoc, endLoc) {\n var comment = {\n type: block ? \"Block\" : \"Line\",\n value: text,\n start: start,\n end: end\n };\n if (options.locations)\n { comment.loc = new SourceLocation(this, startLoc, endLoc); }\n if (options.ranges)\n { comment.range = [start, end]; }\n array.push(comment);\n }\n}\n\n// Each scope gets a bitset that may contain these flags\nvar\n SCOPE_TOP = 1,\n SCOPE_FUNCTION = 2,\n SCOPE_ASYNC = 4,\n SCOPE_GENERATOR = 8,\n SCOPE_ARROW = 16,\n SCOPE_SIMPLE_CATCH = 32,\n SCOPE_SUPER = 64,\n SCOPE_DIRECT_SUPER = 128,\n SCOPE_CLASS_STATIC_BLOCK = 256,\n SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK;\n\nfunction functionFlags(async, generator) {\n return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0)\n}\n\n// Used in checkLVal* and declareName to determine the type of a binding\nvar\n BIND_NONE = 0, // Not a binding\n BIND_VAR = 1, // Var-style binding\n BIND_LEXICAL = 2, // Let- or const-style binding\n BIND_FUNCTION = 3, // Function declaration\n BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding\n BIND_OUTSIDE = 5; // Special case for function names as bound inside the function\n\nvar Parser = function Parser(options, input, startPos) {\n this.options = options = getOptions(options);\n this.sourceFile = options.sourceFile;\n this.keywords = wordsRegexp(keywords$1[options.ecmaVersion >= 6 ? 6 : options.sourceType === \"module\" ? \"5module\" : 5]);\n var reserved = \"\";\n if (options.allowReserved !== true) {\n reserved = reservedWords[options.ecmaVersion >= 6 ? 6 : options.ecmaVersion === 5 ? 5 : 3];\n if (options.sourceType === \"module\") { reserved += \" await\"; }\n }\n this.reservedWords = wordsRegexp(reserved);\n var reservedStrict = (reserved ? reserved + \" \" : \"\") + reservedWords.strict;\n this.reservedWordsStrict = wordsRegexp(reservedStrict);\n this.reservedWordsStrictBind = wordsRegexp(reservedStrict + \" \" + reservedWords.strictBind);\n this.input = String(input);\n\n // Used to signal to callers of `readWord1` whether the word\n // contained any escape sequences. This is needed because words with\n // escape sequences must not be interpreted as keywords.\n this.containsEsc = false;\n\n // Set up token state\n\n // The current position of the tokenizer in the input.\n if (startPos) {\n this.pos = startPos;\n this.lineStart = this.input.lastIndexOf(\"\\n\", startPos - 1) + 1;\n this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;\n } else {\n this.pos = this.lineStart = 0;\n this.curLine = 1;\n }\n\n // Properties of the current token:\n // Its type\n this.type = types$1.eof;\n // For tokens that include more information than their type, the value\n this.value = null;\n // Its start and end offset\n this.start = this.end = this.pos;\n // And, if locations are used, the {line, column} object\n // corresponding to those offsets\n this.startLoc = this.endLoc = this.curPosition();\n\n // Position information for the previous token\n this.lastTokEndLoc = this.lastTokStartLoc = null;\n this.lastTokStart = this.lastTokEnd = this.pos;\n\n // The context stack is used to superficially track syntactic\n // context to predict whether a regular expression is allowed in a\n // given position.\n this.context = this.initialContext();\n this.exprAllowed = true;\n\n // Figure out if it's a module code.\n this.inModule = options.sourceType === \"module\";\n this.strict = this.inModule || this.strictDirective(this.pos);\n\n // Used to signify the start of a potential arrow function\n this.potentialArrowAt = -1;\n this.potentialArrowInForAwait = false;\n\n // Positions to delayed-check that yield/await does not exist in default parameters.\n this.yieldPos = this.awaitPos = this.awaitIdentPos = 0;\n // Labels in scope.\n this.labels = [];\n // Thus-far undefined exports.\n this.undefinedExports = Object.create(null);\n\n // If enabled, skip leading hashbang line.\n if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === \"#!\")\n { this.skipLineComment(2); }\n\n // Scope tracking for duplicate variable names (see scope.js)\n this.scopeStack = [];\n this.enterScope(SCOPE_TOP);\n\n // For RegExp validation\n this.regexpState = null;\n\n // The stack of private names.\n // Each element has two properties: 'declared' and 'used'.\n // When it exited from the outermost class definition, all used private names must be declared.\n this.privateNameStack = [];\n};\n\nvar prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },allowNewDotTarget: { configurable: true },inClassStaticBlock: { configurable: true } };\n\nParser.prototype.parse = function parse () {\n var node = this.options.program || this.startNode();\n this.nextToken();\n return this.parseTopLevel(node)\n};\n\nprototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 };\n\nprototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 && !this.currentVarScope().inClassFieldInit };\n\nprototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 && !this.currentVarScope().inClassFieldInit };\n\nprototypeAccessors.canAwait.get = function () {\n for (var i = this.scopeStack.length - 1; i >= 0; i--) {\n var scope = this.scopeStack[i];\n if (scope.inClassFieldInit || scope.flags & SCOPE_CLASS_STATIC_BLOCK) { return false }\n if (scope.flags & SCOPE_FUNCTION) { return (scope.flags & SCOPE_ASYNC) > 0 }\n }\n return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction\n};\n\nprototypeAccessors.allowSuper.get = function () {\n var ref = this.currentThisScope();\n var flags = ref.flags;\n var inClassFieldInit = ref.inClassFieldInit;\n return (flags & SCOPE_SUPER) > 0 || inClassFieldInit || this.options.allowSuperOutsideMethod\n};\n\nprototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 };\n\nprototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) };\n\nprototypeAccessors.allowNewDotTarget.get = function () {\n var ref = this.currentThisScope();\n var flags = ref.flags;\n var inClassFieldInit = ref.inClassFieldInit;\n return (flags & (SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK)) > 0 || inClassFieldInit\n};\n\nprototypeAccessors.inClassStaticBlock.get = function () {\n return (this.currentVarScope().flags & SCOPE_CLASS_STATIC_BLOCK) > 0\n};\n\nParser.extend = function extend () {\n var plugins = [], len = arguments.length;\n while ( len-- ) plugins[ len ] = arguments[ len ];\n\n var cls = this;\n for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); }\n return cls\n};\n\nParser.parse = function parse (input, options) {\n return new this(options, input).parse()\n};\n\nParser.parseExpressionAt = function parseExpressionAt (input, pos, options) {\n var parser = new this(options, input, pos);\n parser.nextToken();\n return parser.parseExpression()\n};\n\nParser.tokenizer = function tokenizer (input, options) {\n return new this(options, input)\n};\n\nObject.defineProperties( Parser.prototype, prototypeAccessors );\n\nvar pp$9 = Parser.prototype;\n\n// ## Parser utilities\n\nvar literal = /^(?:'((?:\\\\.|[^'\\\\])*?)'|\"((?:\\\\.|[^\"\\\\])*?)\")/;\npp$9.strictDirective = function(start) {\n if (this.options.ecmaVersion < 5) { return false }\n for (;;) {\n // Try to find string literal.\n skipWhiteSpace.lastIndex = start;\n start += skipWhiteSpace.exec(this.input)[0].length;\n var match = literal.exec(this.input.slice(start));\n if (!match) { return false }\n if ((match[1] || match[2]) === \"use strict\") {\n skipWhiteSpace.lastIndex = start + match[0].length;\n var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length;\n var next = this.input.charAt(end);\n return next === \";\" || next === \"}\" ||\n (lineBreak.test(spaceAfter[0]) &&\n !(/[(`.[+\\-/*%<>=,?^&]/.test(next) || next === \"!\" && this.input.charAt(end + 1) === \"=\"))\n }\n start += match[0].length;\n\n // Skip semicolon, if any.\n skipWhiteSpace.lastIndex = start;\n start += skipWhiteSpace.exec(this.input)[0].length;\n if (this.input[start] === \";\")\n { start++; }\n }\n};\n\n// Predicate that tests whether the next token is of the given\n// type, and if yes, consumes it as a side effect.\n\npp$9.eat = function(type) {\n if (this.type === type) {\n this.next();\n return true\n } else {\n return false\n }\n};\n\n// Tests whether parsed token is a contextual keyword.\n\npp$9.isContextual = function(name) {\n return this.type === types$1.name && this.value === name && !this.containsEsc\n};\n\n// Consumes contextual keyword if possible.\n\npp$9.eatContextual = function(name) {\n if (!this.isContextual(name)) { return false }\n this.next();\n return true\n};\n\n// Asserts that following token is given contextual keyword.\n\npp$9.expectContextual = function(name) {\n if (!this.eatContextual(name)) { this.unexpected(); }\n};\n\n// Test whether a semicolon can be inserted at the current position.\n\npp$9.canInsertSemicolon = function() {\n return this.type === types$1.eof ||\n this.type === types$1.braceR ||\n lineBreak.test(this.input.slice(this.lastTokEnd, this.start))\n};\n\npp$9.insertSemicolon = function() {\n if (this.canInsertSemicolon()) {\n if (this.options.onInsertedSemicolon)\n { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }\n return true\n }\n};\n\n// Consume a semicolon, or, failing that, see if we are allowed to\n// pretend that there is a semicolon at this position.\n\npp$9.semicolon = function() {\n if (!this.eat(types$1.semi) && !this.insertSemicolon()) { this.unexpected(); }\n};\n\npp$9.afterTrailingComma = function(tokType, notNext) {\n if (this.type === tokType) {\n if (this.options.onTrailingComma)\n { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }\n if (!notNext)\n { this.next(); }\n return true\n }\n};\n\n// Expect a token of a given type. If found, consume it, otherwise,\n// raise an unexpected token error.\n\npp$9.expect = function(type) {\n this.eat(type) || this.unexpected();\n};\n\n// Raise an unexpected token error.\n\npp$9.unexpected = function(pos) {\n this.raise(pos != null ? pos : this.start, \"Unexpected token\");\n};\n\nvar DestructuringErrors = function DestructuringErrors() {\n this.shorthandAssign =\n this.trailingComma =\n this.parenthesizedAssign =\n this.parenthesizedBind =\n this.doubleProto =\n -1;\n};\n\npp$9.checkPatternErrors = function(refDestructuringErrors, isAssign) {\n if (!refDestructuringErrors) { return }\n if (refDestructuringErrors.trailingComma > -1)\n { this.raiseRecoverable(refDestructuringErrors.trailingComma, \"Comma is not permitted after the rest element\"); }\n var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;\n if (parens > -1) { this.raiseRecoverable(parens, isAssign ? \"Assigning to rvalue\" : \"Parenthesized pattern\"); }\n};\n\npp$9.checkExpressionErrors = function(refDestructuringErrors, andThrow) {\n if (!refDestructuringErrors) { return false }\n var shorthandAssign = refDestructuringErrors.shorthandAssign;\n var doubleProto = refDestructuringErrors.doubleProto;\n if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }\n if (shorthandAssign >= 0)\n { this.raise(shorthandAssign, \"Shorthand property assignments are valid only in destructuring patterns\"); }\n if (doubleProto >= 0)\n { this.raiseRecoverable(doubleProto, \"Redefinition of __proto__ property\"); }\n};\n\npp$9.checkYieldAwaitInDefaultParams = function() {\n if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))\n { this.raise(this.yieldPos, \"Yield expression cannot be a default value\"); }\n if (this.awaitPos)\n { this.raise(this.awaitPos, \"Await expression cannot be a default value\"); }\n};\n\npp$9.isSimpleAssignTarget = function(expr) {\n if (expr.type === \"ParenthesizedExpression\")\n { return this.isSimpleAssignTarget(expr.expression) }\n return expr.type === \"Identifier\" || expr.type === \"MemberExpression\"\n};\n\nvar pp$8 = Parser.prototype;\n\n// ### Statement parsing\n\n// Parse a program. Initializes the parser, reads any number of\n// statements, and wraps them in a Program node. Optionally takes a\n// `program` argument. If present, the statements will be appended\n// to its body instead of creating a new node.\n\npp$8.parseTopLevel = function(node) {\n var exports = Object.create(null);\n if (!node.body) { node.body = []; }\n while (this.type !== types$1.eof) {\n var stmt = this.parseStatement(null, true, exports);\n node.body.push(stmt);\n }\n if (this.inModule)\n { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1)\n {\n var name = list[i];\n\n this.raiseRecoverable(this.undefinedExports[name].start, (\"Export '\" + name + \"' is not defined\"));\n } }\n this.adaptDirectivePrologue(node.body);\n this.next();\n node.sourceType = this.options.sourceType;\n return this.finishNode(node, \"Program\")\n};\n\nvar loopLabel = {kind: \"loop\"}, switchLabel = {kind: \"switch\"};\n\npp$8.isLet = function(context) {\n if (this.options.ecmaVersion < 6 || !this.isContextual(\"let\")) { return false }\n skipWhiteSpace.lastIndex = this.pos;\n var skip = skipWhiteSpace.exec(this.input);\n var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);\n // For ambiguous cases, determine if a LexicalDeclaration (or only a\n // Statement) is allowed here. If context is not empty then only a Statement\n // is allowed. However, `let [` is an explicit negative lookahead for\n // ExpressionStatement, so special-case it first.\n if (nextCh === 91 || nextCh === 92) { return true } // '[', '/'\n if (context) { return false }\n\n if (nextCh === 123 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '{', astral\n if (isIdentifierStart(nextCh, true)) {\n var pos = next + 1;\n while (isIdentifierChar(nextCh = this.input.charCodeAt(pos), true)) { ++pos; }\n if (nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true }\n var ident = this.input.slice(next, pos);\n if (!keywordRelationalOperator.test(ident)) { return true }\n }\n return false\n};\n\n// check 'async [no LineTerminator here] function'\n// - 'async /*foo*/ function' is OK.\n// - 'async /*\\n*/ function' is invalid.\npp$8.isAsyncFunction = function() {\n if (this.options.ecmaVersion < 8 || !this.isContextual(\"async\"))\n { return false }\n\n skipWhiteSpace.lastIndex = this.pos;\n var skip = skipWhiteSpace.exec(this.input);\n var next = this.pos + skip[0].length, after;\n return !lineBreak.test(this.input.slice(this.pos, next)) &&\n this.input.slice(next, next + 8) === \"function\" &&\n (next + 8 === this.input.length ||\n !(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00))\n};\n\n// Parse a single statement.\n//\n// If expecting a statement and finding a slash operator, parse a\n// regular expression literal. This is to handle cases like\n// `if (foo) /blah/.exec(foo)`, where looking at the previous token\n// does not help.\n\npp$8.parseStatement = function(context, topLevel, exports) {\n var starttype = this.type, node = this.startNode(), kind;\n\n if (this.isLet(context)) {\n starttype = types$1._var;\n kind = \"let\";\n }\n\n // Most types of statements are recognized by the keyword they\n // start with. Many are trivial to parse, some require a bit of\n // complexity.\n\n switch (starttype) {\n case types$1._break: case types$1._continue: return this.parseBreakContinueStatement(node, starttype.keyword)\n case types$1._debugger: return this.parseDebuggerStatement(node)\n case types$1._do: return this.parseDoStatement(node)\n case types$1._for: return this.parseForStatement(node)\n case types$1._function:\n // Function as sole body of either an if statement or a labeled statement\n // works, but not when it is part of a labeled statement that is the sole\n // body of an if statement.\n if ((context && (this.strict || context !== \"if\" && context !== \"label\")) && this.options.ecmaVersion >= 6) { this.unexpected(); }\n return this.parseFunctionStatement(node, false, !context)\n case types$1._class:\n if (context) { this.unexpected(); }\n return this.parseClass(node, true)\n case types$1._if: return this.parseIfStatement(node)\n case types$1._return: return this.parseReturnStatement(node)\n case types$1._switch: return this.parseSwitchStatement(node)\n case types$1._throw: return this.parseThrowStatement(node)\n case types$1._try: return this.parseTryStatement(node)\n case types$1._const: case types$1._var:\n kind = kind || this.value;\n if (context && kind !== \"var\") { this.unexpected(); }\n return this.parseVarStatement(node, kind)\n case types$1._while: return this.parseWhileStatement(node)\n case types$1._with: return this.parseWithStatement(node)\n case types$1.braceL: return this.parseBlock(true, node)\n case types$1.semi: return this.parseEmptyStatement(node)\n case types$1._export:\n case types$1._import:\n if (this.options.ecmaVersion > 10 && starttype === types$1._import) {\n skipWhiteSpace.lastIndex = this.pos;\n var skip = skipWhiteSpace.exec(this.input);\n var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);\n if (nextCh === 40 || nextCh === 46) // '(' or '.'\n { return this.parseExpressionStatement(node, this.parseExpression()) }\n }\n\n if (!this.options.allowImportExportEverywhere) {\n if (!topLevel)\n { this.raise(this.start, \"'import' and 'export' may only appear at the top level\"); }\n if (!this.inModule)\n { this.raise(this.start, \"'import' and 'export' may appear only with 'sourceType: module'\"); }\n }\n return starttype === types$1._import ? this.parseImport(node) : this.parseExport(node, exports)\n\n // If the statement does not start with a statement keyword or a\n // brace, it's an ExpressionStatement or LabeledStatement. We\n // simply start parsing an expression, and afterwards, if the\n // next token is a colon and the expression was a simple\n // Identifier node, we switch to interpreting it as a label.\n default:\n if (this.isAsyncFunction()) {\n if (context) { this.unexpected(); }\n this.next();\n return this.parseFunctionStatement(node, true, !context)\n }\n\n var maybeName = this.value, expr = this.parseExpression();\n if (starttype === types$1.name && expr.type === \"Identifier\" && this.eat(types$1.colon))\n { return this.parseLabeledStatement(node, maybeName, expr, context) }\n else { return this.parseExpressionStatement(node, expr) }\n }\n};\n\npp$8.parseBreakContinueStatement = function(node, keyword) {\n var isBreak = keyword === \"break\";\n this.next();\n if (this.eat(types$1.semi) || this.insertSemicolon()) { node.label = null; }\n else if (this.type !== types$1.name) { this.unexpected(); }\n else {\n node.label = this.parseIdent();\n this.semicolon();\n }\n\n // Verify that there is an actual destination to break or\n // continue to.\n var i = 0;\n for (; i < this.labels.length; ++i) {\n var lab = this.labels[i];\n if (node.label == null || lab.name === node.label.name) {\n if (lab.kind != null && (isBreak || lab.kind === \"loop\")) { break }\n if (node.label && isBreak) { break }\n }\n }\n if (i === this.labels.length) { this.raise(node.start, \"Unsyntactic \" + keyword); }\n return this.finishNode(node, isBreak ? \"BreakStatement\" : \"ContinueStatement\")\n};\n\npp$8.parseDebuggerStatement = function(node) {\n this.next();\n this.semicolon();\n return this.finishNode(node, \"DebuggerStatement\")\n};\n\npp$8.parseDoStatement = function(node) {\n this.next();\n this.labels.push(loopLabel);\n node.body = this.parseStatement(\"do\");\n this.labels.pop();\n this.expect(types$1._while);\n node.test = this.parseParenExpression();\n if (this.options.ecmaVersion >= 6)\n { this.eat(types$1.semi); }\n else\n { this.semicolon(); }\n return this.finishNode(node, \"DoWhileStatement\")\n};\n\n// Disambiguating between a `for` and a `for`/`in` or `for`/`of`\n// loop is non-trivial. Basically, we have to parse the init `var`\n// statement or expression, disallowing the `in` operator (see\n// the second parameter to `parseExpression`), and then check\n// whether the next token is `in` or `of`. When there is no init\n// part (semicolon immediately after the opening parenthesis), it\n// is a regular `for` loop.\n\npp$8.parseForStatement = function(node) {\n this.next();\n var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual(\"await\")) ? this.lastTokStart : -1;\n this.labels.push(loopLabel);\n this.enterScope(0);\n this.expect(types$1.parenL);\n if (this.type === types$1.semi) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, null)\n }\n var isLet = this.isLet();\n if (this.type === types$1._var || this.type === types$1._const || isLet) {\n var init$1 = this.startNode(), kind = isLet ? \"let\" : this.value;\n this.next();\n this.parseVar(init$1, true, kind);\n this.finishNode(init$1, \"VariableDeclaration\");\n if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual(\"of\"))) && init$1.declarations.length === 1) {\n if (this.options.ecmaVersion >= 9) {\n if (this.type === types$1._in) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n } else { node.await = awaitAt > -1; }\n }\n return this.parseForIn(node, init$1)\n }\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, init$1)\n }\n var startsWithLet = this.isContextual(\"let\"), isForOf = false;\n var refDestructuringErrors = new DestructuringErrors;\n var init = this.parseExpression(awaitAt > -1 ? \"await\" : true, refDestructuringErrors);\n if (this.type === types$1._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual(\"of\"))) {\n if (this.options.ecmaVersion >= 9) {\n if (this.type === types$1._in) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n } else { node.await = awaitAt > -1; }\n }\n if (startsWithLet && isForOf) { this.raise(init.start, \"The left-hand side of a for-of loop may not start with 'let'.\"); }\n this.toAssignable(init, false, refDestructuringErrors);\n this.checkLValPattern(init);\n return this.parseForIn(node, init)\n } else {\n this.checkExpressionErrors(refDestructuringErrors, true);\n }\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, init)\n};\n\npp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) {\n this.next();\n return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync)\n};\n\npp$8.parseIfStatement = function(node) {\n this.next();\n node.test = this.parseParenExpression();\n // allow function declarations in branches, but only in non-strict mode\n node.consequent = this.parseStatement(\"if\");\n node.alternate = this.eat(types$1._else) ? this.parseStatement(\"if\") : null;\n return this.finishNode(node, \"IfStatement\")\n};\n\npp$8.parseReturnStatement = function(node) {\n if (!this.inFunction && !this.options.allowReturnOutsideFunction)\n { this.raise(this.start, \"'return' outside of function\"); }\n this.next();\n\n // In `return` (and `break`/`continue`), the keywords with\n // optional arguments, we eagerly look for a semicolon or the\n // possibility to insert one.\n\n if (this.eat(types$1.semi) || this.insertSemicolon()) { node.argument = null; }\n else { node.argument = this.parseExpression(); this.semicolon(); }\n return this.finishNode(node, \"ReturnStatement\")\n};\n\npp$8.parseSwitchStatement = function(node) {\n this.next();\n node.discriminant = this.parseParenExpression();\n node.cases = [];\n this.expect(types$1.braceL);\n this.labels.push(switchLabel);\n this.enterScope(0);\n\n // Statements under must be grouped (by label) in SwitchCase\n // nodes. `cur` is used to keep the node that we are currently\n // adding statements to.\n\n var cur;\n for (var sawDefault = false; this.type !== types$1.braceR;) {\n if (this.type === types$1._case || this.type === types$1._default) {\n var isCase = this.type === types$1._case;\n if (cur) { this.finishNode(cur, \"SwitchCase\"); }\n node.cases.push(cur = this.startNode());\n cur.consequent = [];\n this.next();\n if (isCase) {\n cur.test = this.parseExpression();\n } else {\n if (sawDefault) { this.raiseRecoverable(this.lastTokStart, \"Multiple default clauses\"); }\n sawDefault = true;\n cur.test = null;\n }\n this.expect(types$1.colon);\n } else {\n if (!cur) { this.unexpected(); }\n cur.consequent.push(this.parseStatement(null));\n }\n }\n this.exitScope();\n if (cur) { this.finishNode(cur, \"SwitchCase\"); }\n this.next(); // Closing brace\n this.labels.pop();\n return this.finishNode(node, \"SwitchStatement\")\n};\n\npp$8.parseThrowStatement = function(node) {\n this.next();\n if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))\n { this.raise(this.lastTokEnd, \"Illegal newline after throw\"); }\n node.argument = this.parseExpression();\n this.semicolon();\n return this.finishNode(node, \"ThrowStatement\")\n};\n\n// Reused empty array added for node fields that are always empty.\n\nvar empty$1 = [];\n\npp$8.parseTryStatement = function(node) {\n this.next();\n node.block = this.parseBlock();\n node.handler = null;\n if (this.type === types$1._catch) {\n var clause = this.startNode();\n this.next();\n if (this.eat(types$1.parenL)) {\n clause.param = this.parseBindingAtom();\n var simple = clause.param.type === \"Identifier\";\n this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0);\n this.checkLValPattern(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL);\n this.expect(types$1.parenR);\n } else {\n if (this.options.ecmaVersion < 10) { this.unexpected(); }\n clause.param = null;\n this.enterScope(0);\n }\n clause.body = this.parseBlock(false);\n this.exitScope();\n node.handler = this.finishNode(clause, \"CatchClause\");\n }\n node.finalizer = this.eat(types$1._finally) ? this.parseBlock() : null;\n if (!node.handler && !node.finalizer)\n { this.raise(node.start, \"Missing catch or finally clause\"); }\n return this.finishNode(node, \"TryStatement\")\n};\n\npp$8.parseVarStatement = function(node, kind) {\n this.next();\n this.parseVar(node, false, kind);\n this.semicolon();\n return this.finishNode(node, \"VariableDeclaration\")\n};\n\npp$8.parseWhileStatement = function(node) {\n this.next();\n node.test = this.parseParenExpression();\n this.labels.push(loopLabel);\n node.body = this.parseStatement(\"while\");\n this.labels.pop();\n return this.finishNode(node, \"WhileStatement\")\n};\n\npp$8.parseWithStatement = function(node) {\n if (this.strict) { this.raise(this.start, \"'with' in strict mode\"); }\n this.next();\n node.object = this.parseParenExpression();\n node.body = this.parseStatement(\"with\");\n return this.finishNode(node, \"WithStatement\")\n};\n\npp$8.parseEmptyStatement = function(node) {\n this.next();\n return this.finishNode(node, \"EmptyStatement\")\n};\n\npp$8.parseLabeledStatement = function(node, maybeName, expr, context) {\n for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1)\n {\n var label = list[i$1];\n\n if (label.name === maybeName)\n { this.raise(expr.start, \"Label '\" + maybeName + \"' is already declared\");\n } }\n var kind = this.type.isLoop ? \"loop\" : this.type === types$1._switch ? \"switch\" : null;\n for (var i = this.labels.length - 1; i >= 0; i--) {\n var label$1 = this.labels[i];\n if (label$1.statementStart === node.start) {\n // Update information about previous labels on this node\n label$1.statementStart = this.start;\n label$1.kind = kind;\n } else { break }\n }\n this.labels.push({name: maybeName, kind: kind, statementStart: this.start});\n node.body = this.parseStatement(context ? context.indexOf(\"label\") === -1 ? context + \"label\" : context : \"label\");\n this.labels.pop();\n node.label = expr;\n return this.finishNode(node, \"LabeledStatement\")\n};\n\npp$8.parseExpressionStatement = function(node, expr) {\n node.expression = expr;\n this.semicolon();\n return this.finishNode(node, \"ExpressionStatement\")\n};\n\n// Parse a semicolon-enclosed block of statements, handling `\"use\n// strict\"` declarations when `allowStrict` is true (used for\n// function bodies).\n\npp$8.parseBlock = function(createNewLexicalScope, node, exitStrict) {\n if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;\n if ( node === void 0 ) node = this.startNode();\n\n node.body = [];\n this.expect(types$1.braceL);\n if (createNewLexicalScope) { this.enterScope(0); }\n while (this.type !== types$1.braceR) {\n var stmt = this.parseStatement(null);\n node.body.push(stmt);\n }\n if (exitStrict) { this.strict = false; }\n this.next();\n if (createNewLexicalScope) { this.exitScope(); }\n return this.finishNode(node, \"BlockStatement\")\n};\n\n// Parse a regular `for` loop. The disambiguation code in\n// `parseStatement` will already have parsed the init statement or\n// expression.\n\npp$8.parseFor = function(node, init) {\n node.init = init;\n this.expect(types$1.semi);\n node.test = this.type === types$1.semi ? null : this.parseExpression();\n this.expect(types$1.semi);\n node.update = this.type === types$1.parenR ? null : this.parseExpression();\n this.expect(types$1.parenR);\n node.body = this.parseStatement(\"for\");\n this.exitScope();\n this.labels.pop();\n return this.finishNode(node, \"ForStatement\")\n};\n\n// Parse a `for`/`in` and `for`/`of` loop, which are almost\n// same from parser's perspective.\n\npp$8.parseForIn = function(node, init) {\n var isForIn = this.type === types$1._in;\n this.next();\n\n if (\n init.type === \"VariableDeclaration\" &&\n init.declarations[0].init != null &&\n (\n !isForIn ||\n this.options.ecmaVersion < 8 ||\n this.strict ||\n init.kind !== \"var\" ||\n init.declarations[0].id.type !== \"Identifier\"\n )\n ) {\n this.raise(\n init.start,\n ((isForIn ? \"for-in\" : \"for-of\") + \" loop variable declaration may not have an initializer\")\n );\n }\n node.left = init;\n node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign();\n this.expect(types$1.parenR);\n node.body = this.parseStatement(\"for\");\n this.exitScope();\n this.labels.pop();\n return this.finishNode(node, isForIn ? \"ForInStatement\" : \"ForOfStatement\")\n};\n\n// Parse a list of variable declarations.\n\npp$8.parseVar = function(node, isFor, kind) {\n node.declarations = [];\n node.kind = kind;\n for (;;) {\n var decl = this.startNode();\n this.parseVarId(decl, kind);\n if (this.eat(types$1.eq)) {\n decl.init = this.parseMaybeAssign(isFor);\n } else if (kind === \"const\" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual(\"of\")))) {\n this.unexpected();\n } else if (decl.id.type !== \"Identifier\" && !(isFor && (this.type === types$1._in || this.isContextual(\"of\")))) {\n this.raise(this.lastTokEnd, \"Complex binding patterns require an initialization value\");\n } else {\n decl.init = null;\n }\n node.declarations.push(this.finishNode(decl, \"VariableDeclarator\"));\n if (!this.eat(types$1.comma)) { break }\n }\n return node\n};\n\npp$8.parseVarId = function(decl, kind) {\n decl.id = this.parseBindingAtom();\n this.checkLValPattern(decl.id, kind === \"var\" ? BIND_VAR : BIND_LEXICAL, false);\n};\n\nvar FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4;\n\n// Parse a function declaration or literal (depending on the\n// `statement & FUNC_STATEMENT`).\n\n// Remove `allowExpressionBody` for 7.0.0, as it is only called with false\npp$8.parseFunction = function(node, statement, allowExpressionBody, isAsync, forInit) {\n this.initFunction(node);\n if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) {\n if (this.type === types$1.star && (statement & FUNC_HANGING_STATEMENT))\n { this.unexpected(); }\n node.generator = this.eat(types$1.star);\n }\n if (this.options.ecmaVersion >= 8)\n { node.async = !!isAsync; }\n\n if (statement & FUNC_STATEMENT) {\n node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types$1.name ? null : this.parseIdent();\n if (node.id && !(statement & FUNC_HANGING_STATEMENT))\n // If it is a regular function declaration in sloppy mode, then it is\n // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding\n // mode depends on properties of the current scope (see\n // treatFunctionsAsVar).\n { this.checkLValSimple(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); }\n }\n\n var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.awaitIdentPos = 0;\n this.enterScope(functionFlags(node.async, node.generator));\n\n if (!(statement & FUNC_STATEMENT))\n { node.id = this.type === types$1.name ? this.parseIdent() : null; }\n\n this.parseFunctionParams(node);\n this.parseFunctionBody(node, allowExpressionBody, false, forInit);\n\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.awaitIdentPos = oldAwaitIdentPos;\n return this.finishNode(node, (statement & FUNC_STATEMENT) ? \"FunctionDeclaration\" : \"FunctionExpression\")\n};\n\npp$8.parseFunctionParams = function(node) {\n this.expect(types$1.parenL);\n node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8);\n this.checkYieldAwaitInDefaultParams();\n};\n\n// Parse a class declaration or literal (depending on the\n// `isStatement` parameter).\n\npp$8.parseClass = function(node, isStatement) {\n this.next();\n\n // ecma-262 14.6 Class Definitions\n // A class definition is always strict mode code.\n var oldStrict = this.strict;\n this.strict = true;\n\n this.parseClassId(node, isStatement);\n this.parseClassSuper(node);\n var privateNameMap = this.enterClassBody();\n var classBody = this.startNode();\n var hadConstructor = false;\n classBody.body = [];\n this.expect(types$1.braceL);\n while (this.type !== types$1.braceR) {\n var element = this.parseClassElement(node.superClass !== null);\n if (element) {\n classBody.body.push(element);\n if (element.type === \"MethodDefinition\" && element.kind === \"constructor\") {\n if (hadConstructor) { this.raise(element.start, \"Duplicate constructor in the same class\"); }\n hadConstructor = true;\n } else if (element.key && element.key.type === \"PrivateIdentifier\" && isPrivateNameConflicted(privateNameMap, element)) {\n this.raiseRecoverable(element.key.start, (\"Identifier '#\" + (element.key.name) + \"' has already been declared\"));\n }\n }\n }\n this.strict = oldStrict;\n this.next();\n node.body = this.finishNode(classBody, \"ClassBody\");\n this.exitClassBody();\n return this.finishNode(node, isStatement ? \"ClassDeclaration\" : \"ClassExpression\")\n};\n\npp$8.parseClassElement = function(constructorAllowsSuper) {\n if (this.eat(types$1.semi)) { return null }\n\n var ecmaVersion = this.options.ecmaVersion;\n var node = this.startNode();\n var keyName = \"\";\n var isGenerator = false;\n var isAsync = false;\n var kind = \"method\";\n var isStatic = false;\n\n if (this.eatContextual(\"static\")) {\n // Parse static init block\n if (ecmaVersion >= 13 && this.eat(types$1.braceL)) {\n this.parseClassStaticBlock(node);\n return node\n }\n if (this.isClassElementNameStart() || this.type === types$1.star) {\n isStatic = true;\n } else {\n keyName = \"static\";\n }\n }\n node.static = isStatic;\n if (!keyName && ecmaVersion >= 8 && this.eatContextual(\"async\")) {\n if ((this.isClassElementNameStart() || this.type === types$1.star) && !this.canInsertSemicolon()) {\n isAsync = true;\n } else {\n keyName = \"async\";\n }\n }\n if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types$1.star)) {\n isGenerator = true;\n }\n if (!keyName && !isAsync && !isGenerator) {\n var lastValue = this.value;\n if (this.eatContextual(\"get\") || this.eatContextual(\"set\")) {\n if (this.isClassElementNameStart()) {\n kind = lastValue;\n } else {\n keyName = lastValue;\n }\n }\n }\n\n // Parse element name\n if (keyName) {\n // 'async', 'get', 'set', or 'static' were not a keyword contextually.\n // The last token is any of those. Make it the element name.\n node.computed = false;\n node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc);\n node.key.name = keyName;\n this.finishNode(node.key, \"Identifier\");\n } else {\n this.parseClassElementName(node);\n }\n\n // Parse element value\n if (ecmaVersion < 13 || this.type === types$1.parenL || kind !== \"method\" || isGenerator || isAsync) {\n var isConstructor = !node.static && checkKeyName(node, \"constructor\");\n var allowsDirectSuper = isConstructor && constructorAllowsSuper;\n // Couldn't move this check into the 'parseClassMethod' method for backward compatibility.\n if (isConstructor && kind !== \"method\") { this.raise(node.key.start, \"Constructor can't have get/set modifier\"); }\n node.kind = isConstructor ? \"constructor\" : kind;\n this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper);\n } else {\n this.parseClassField(node);\n }\n\n return node\n};\n\npp$8.isClassElementNameStart = function() {\n return (\n this.type === types$1.name ||\n this.type === types$1.privateId ||\n this.type === types$1.num ||\n this.type === types$1.string ||\n this.type === types$1.bracketL ||\n this.type.keyword\n )\n};\n\npp$8.parseClassElementName = function(element) {\n if (this.type === types$1.privateId) {\n if (this.value === \"constructor\") {\n this.raise(this.start, \"Classes can't have an element named '#constructor'\");\n }\n element.computed = false;\n element.key = this.parsePrivateIdent();\n } else {\n this.parsePropertyName(element);\n }\n};\n\npp$8.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) {\n // Check key and flags\n var key = method.key;\n if (method.kind === \"constructor\") {\n if (isGenerator) { this.raise(key.start, \"Constructor can't be a generator\"); }\n if (isAsync) { this.raise(key.start, \"Constructor can't be an async method\"); }\n } else if (method.static && checkKeyName(method, \"prototype\")) {\n this.raise(key.start, \"Classes may not have a static property named prototype\");\n }\n\n // Parse value\n var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);\n\n // Check value\n if (method.kind === \"get\" && value.params.length !== 0)\n { this.raiseRecoverable(value.start, \"getter should have no params\"); }\n if (method.kind === \"set\" && value.params.length !== 1)\n { this.raiseRecoverable(value.start, \"setter should have exactly one param\"); }\n if (method.kind === \"set\" && value.params[0].type === \"RestElement\")\n { this.raiseRecoverable(value.params[0].start, \"Setter cannot use rest params\"); }\n\n return this.finishNode(method, \"MethodDefinition\")\n};\n\npp$8.parseClassField = function(field) {\n if (checkKeyName(field, \"constructor\")) {\n this.raise(field.key.start, \"Classes can't have a field named 'constructor'\");\n } else if (field.static && checkKeyName(field, \"prototype\")) {\n this.raise(field.key.start, \"Classes can't have a static field named 'prototype'\");\n }\n\n if (this.eat(types$1.eq)) {\n // To raise SyntaxError if 'arguments' exists in the initializer.\n var scope = this.currentThisScope();\n var inClassFieldInit = scope.inClassFieldInit;\n scope.inClassFieldInit = true;\n field.value = this.parseMaybeAssign();\n scope.inClassFieldInit = inClassFieldInit;\n } else {\n field.value = null;\n }\n this.semicolon();\n\n return this.finishNode(field, \"PropertyDefinition\")\n};\n\npp$8.parseClassStaticBlock = function(node) {\n node.body = [];\n\n var oldLabels = this.labels;\n this.labels = [];\n this.enterScope(SCOPE_CLASS_STATIC_BLOCK | SCOPE_SUPER);\n while (this.type !== types$1.braceR) {\n var stmt = this.parseStatement(null);\n node.body.push(stmt);\n }\n this.next();\n this.exitScope();\n this.labels = oldLabels;\n\n return this.finishNode(node, \"StaticBlock\")\n};\n\npp$8.parseClassId = function(node, isStatement) {\n if (this.type === types$1.name) {\n node.id = this.parseIdent();\n if (isStatement)\n { this.checkLValSimple(node.id, BIND_LEXICAL, false); }\n } else {\n if (isStatement === true)\n { this.unexpected(); }\n node.id = null;\n }\n};\n\npp$8.parseClassSuper = function(node) {\n node.superClass = this.eat(types$1._extends) ? this.parseExprSubscripts(null, false) : null;\n};\n\npp$8.enterClassBody = function() {\n var element = {declared: Object.create(null), used: []};\n this.privateNameStack.push(element);\n return element.declared\n};\n\npp$8.exitClassBody = function() {\n var ref = this.privateNameStack.pop();\n var declared = ref.declared;\n var used = ref.used;\n var len = this.privateNameStack.length;\n var parent = len === 0 ? null : this.privateNameStack[len - 1];\n for (var i = 0; i < used.length; ++i) {\n var id = used[i];\n if (!hasOwn(declared, id.name)) {\n if (parent) {\n parent.used.push(id);\n } else {\n this.raiseRecoverable(id.start, (\"Private field '#\" + (id.name) + \"' must be declared in an enclosing class\"));\n }\n }\n }\n};\n\nfunction isPrivateNameConflicted(privateNameMap, element) {\n var name = element.key.name;\n var curr = privateNameMap[name];\n\n var next = \"true\";\n if (element.type === \"MethodDefinition\" && (element.kind === \"get\" || element.kind === \"set\")) {\n next = (element.static ? \"s\" : \"i\") + element.kind;\n }\n\n // `class { get #a(){}; static set #a(_){} }` is also conflict.\n if (\n curr === \"iget\" && next === \"iset\" ||\n curr === \"iset\" && next === \"iget\" ||\n curr === \"sget\" && next === \"sset\" ||\n curr === \"sset\" && next === \"sget\"\n ) {\n privateNameMap[name] = \"true\";\n return false\n } else if (!curr) {\n privateNameMap[name] = next;\n return false\n } else {\n return true\n }\n}\n\nfunction checkKeyName(node, name) {\n var computed = node.computed;\n var key = node.key;\n return !computed && (\n key.type === \"Identifier\" && key.name === name ||\n key.type === \"Literal\" && key.value === name\n )\n}\n\n// Parses module export declaration.\n\npp$8.parseExport = function(node, exports) {\n this.next();\n // export * from '...'\n if (this.eat(types$1.star)) {\n if (this.options.ecmaVersion >= 11) {\n if (this.eatContextual(\"as\")) {\n node.exported = this.parseModuleExportName();\n this.checkExport(exports, node.exported, this.lastTokStart);\n } else {\n node.exported = null;\n }\n }\n this.expectContextual(\"from\");\n if (this.type !== types$1.string) { this.unexpected(); }\n node.source = this.parseExprAtom();\n this.semicolon();\n return this.finishNode(node, \"ExportAllDeclaration\")\n }\n if (this.eat(types$1._default)) { // export default ...\n this.checkExport(exports, \"default\", this.lastTokStart);\n var isAsync;\n if (this.type === types$1._function || (isAsync = this.isAsyncFunction())) {\n var fNode = this.startNode();\n this.next();\n if (isAsync) { this.next(); }\n node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync);\n } else if (this.type === types$1._class) {\n var cNode = this.startNode();\n node.declaration = this.parseClass(cNode, \"nullableID\");\n } else {\n node.declaration = this.parseMaybeAssign();\n this.semicolon();\n }\n return this.finishNode(node, \"ExportDefaultDeclaration\")\n }\n // export var|const|let|function|class ...\n if (this.shouldParseExportStatement()) {\n node.declaration = this.parseStatement(null);\n if (node.declaration.type === \"VariableDeclaration\")\n { this.checkVariableExport(exports, node.declaration.declarations); }\n else\n { this.checkExport(exports, node.declaration.id, node.declaration.id.start); }\n node.specifiers = [];\n node.source = null;\n } else { // export { x, y as z } [from '...']\n node.declaration = null;\n node.specifiers = this.parseExportSpecifiers(exports);\n if (this.eatContextual(\"from\")) {\n if (this.type !== types$1.string) { this.unexpected(); }\n node.source = this.parseExprAtom();\n } else {\n for (var i = 0, list = node.specifiers; i < list.length; i += 1) {\n // check for keywords used as local names\n var spec = list[i];\n\n this.checkUnreserved(spec.local);\n // check if export is defined\n this.checkLocalExport(spec.local);\n\n if (spec.local.type === \"Literal\") {\n this.raise(spec.local.start, \"A string literal cannot be used as an exported binding without `from`.\");\n }\n }\n\n node.source = null;\n }\n this.semicolon();\n }\n return this.finishNode(node, \"ExportNamedDeclaration\")\n};\n\npp$8.checkExport = function(exports, name, pos) {\n if (!exports) { return }\n if (typeof name !== \"string\")\n { name = name.type === \"Identifier\" ? name.name : name.value; }\n if (hasOwn(exports, name))\n { this.raiseRecoverable(pos, \"Duplicate export '\" + name + \"'\"); }\n exports[name] = true;\n};\n\npp$8.checkPatternExport = function(exports, pat) {\n var type = pat.type;\n if (type === \"Identifier\")\n { this.checkExport(exports, pat, pat.start); }\n else if (type === \"ObjectPattern\")\n { for (var i = 0, list = pat.properties; i < list.length; i += 1)\n {\n var prop = list[i];\n\n this.checkPatternExport(exports, prop);\n } }\n else if (type === \"ArrayPattern\")\n { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {\n var elt = list$1[i$1];\n\n if (elt) { this.checkPatternExport(exports, elt); }\n } }\n else if (type === \"Property\")\n { this.checkPatternExport(exports, pat.value); }\n else if (type === \"AssignmentPattern\")\n { this.checkPatternExport(exports, pat.left); }\n else if (type === \"RestElement\")\n { this.checkPatternExport(exports, pat.argument); }\n else if (type === \"ParenthesizedExpression\")\n { this.checkPatternExport(exports, pat.expression); }\n};\n\npp$8.checkVariableExport = function(exports, decls) {\n if (!exports) { return }\n for (var i = 0, list = decls; i < list.length; i += 1)\n {\n var decl = list[i];\n\n this.checkPatternExport(exports, decl.id);\n }\n};\n\npp$8.shouldParseExportStatement = function() {\n return this.type.keyword === \"var\" ||\n this.type.keyword === \"const\" ||\n this.type.keyword === \"class\" ||\n this.type.keyword === \"function\" ||\n this.isLet() ||\n this.isAsyncFunction()\n};\n\n// Parses a comma-separated list of module exports.\n\npp$8.parseExportSpecifiers = function(exports) {\n var nodes = [], first = true;\n // export { x, y as z } [from '...']\n this.expect(types$1.braceL);\n while (!this.eat(types$1.braceR)) {\n if (!first) {\n this.expect(types$1.comma);\n if (this.afterTrailingComma(types$1.braceR)) { break }\n } else { first = false; }\n\n var node = this.startNode();\n node.local = this.parseModuleExportName();\n node.exported = this.eatContextual(\"as\") ? this.parseModuleExportName() : node.local;\n this.checkExport(\n exports,\n node.exported,\n node.exported.start\n );\n nodes.push(this.finishNode(node, \"ExportSpecifier\"));\n }\n return nodes\n};\n\n// Parses import declaration.\n\npp$8.parseImport = function(node) {\n this.next();\n // import '...'\n if (this.type === types$1.string) {\n node.specifiers = empty$1;\n node.source = this.parseExprAtom();\n } else {\n node.specifiers = this.parseImportSpecifiers();\n this.expectContextual(\"from\");\n node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected();\n }\n this.semicolon();\n return this.finishNode(node, \"ImportDeclaration\")\n};\n\n// Parses a comma-separated list of module imports.\n\npp$8.parseImportSpecifiers = function() {\n var nodes = [], first = true;\n if (this.type === types$1.name) {\n // import defaultObj, { x, y as z } from '...'\n var node = this.startNode();\n node.local = this.parseIdent();\n this.checkLValSimple(node.local, BIND_LEXICAL);\n nodes.push(this.finishNode(node, \"ImportDefaultSpecifier\"));\n if (!this.eat(types$1.comma)) { return nodes }\n }\n if (this.type === types$1.star) {\n var node$1 = this.startNode();\n this.next();\n this.expectContextual(\"as\");\n node$1.local = this.parseIdent();\n this.checkLValSimple(node$1.local, BIND_LEXICAL);\n nodes.push(this.finishNode(node$1, \"ImportNamespaceSpecifier\"));\n return nodes\n }\n this.expect(types$1.braceL);\n while (!this.eat(types$1.braceR)) {\n if (!first) {\n this.expect(types$1.comma);\n if (this.afterTrailingComma(types$1.braceR)) { break }\n } else { first = false; }\n\n var node$2 = this.startNode();\n node$2.imported = this.parseModuleExportName();\n if (this.eatContextual(\"as\")) {\n node$2.local = this.parseIdent();\n } else {\n this.checkUnreserved(node$2.imported);\n node$2.local = node$2.imported;\n }\n this.checkLValSimple(node$2.local, BIND_LEXICAL);\n nodes.push(this.finishNode(node$2, \"ImportSpecifier\"));\n }\n return nodes\n};\n\npp$8.parseModuleExportName = function() {\n if (this.options.ecmaVersion >= 13 && this.type === types$1.string) {\n var stringLiteral = this.parseLiteral(this.value);\n if (loneSurrogate.test(stringLiteral.value)) {\n this.raise(stringLiteral.start, \"An export name cannot include a lone surrogate.\");\n }\n return stringLiteral\n }\n return this.parseIdent(true)\n};\n\n// Set `ExpressionStatement#directive` property for directive prologues.\npp$8.adaptDirectivePrologue = function(statements) {\n for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {\n statements[i].directive = statements[i].expression.raw.slice(1, -1);\n }\n};\npp$8.isDirectiveCandidate = function(statement) {\n return (\n this.options.ecmaVersion >= 5 &&\n statement.type === \"ExpressionStatement\" &&\n statement.expression.type === \"Literal\" &&\n typeof statement.expression.value === \"string\" &&\n // Reject parenthesized strings.\n (this.input[statement.start] === \"\\\"\" || this.input[statement.start] === \"'\")\n )\n};\n\nvar pp$7 = Parser.prototype;\n\n// Convert existing expression atom to assignable pattern\n// if possible.\n\npp$7.toAssignable = function(node, isBinding, refDestructuringErrors) {\n if (this.options.ecmaVersion >= 6 && node) {\n switch (node.type) {\n case \"Identifier\":\n if (this.inAsync && node.name === \"await\")\n { this.raise(node.start, \"Cannot use 'await' as identifier inside an async function\"); }\n break\n\n case \"ObjectPattern\":\n case \"ArrayPattern\":\n case \"AssignmentPattern\":\n case \"RestElement\":\n break\n\n case \"ObjectExpression\":\n node.type = \"ObjectPattern\";\n if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n for (var i = 0, list = node.properties; i < list.length; i += 1) {\n var prop = list[i];\n\n this.toAssignable(prop, isBinding);\n // Early error:\n // AssignmentRestProperty[Yield, Await] :\n // `...` DestructuringAssignmentTarget[Yield, Await]\n //\n // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.\n if (\n prop.type === \"RestElement\" &&\n (prop.argument.type === \"ArrayPattern\" || prop.argument.type === \"ObjectPattern\")\n ) {\n this.raise(prop.argument.start, \"Unexpected token\");\n }\n }\n break\n\n case \"Property\":\n // AssignmentProperty has type === \"Property\"\n if (node.kind !== \"init\") { this.raise(node.key.start, \"Object pattern can't contain getter or setter\"); }\n this.toAssignable(node.value, isBinding);\n break\n\n case \"ArrayExpression\":\n node.type = \"ArrayPattern\";\n if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n this.toAssignableList(node.elements, isBinding);\n break\n\n case \"SpreadElement\":\n node.type = \"RestElement\";\n this.toAssignable(node.argument, isBinding);\n if (node.argument.type === \"AssignmentPattern\")\n { this.raise(node.argument.start, \"Rest elements cannot have a default value\"); }\n break\n\n case \"AssignmentExpression\":\n if (node.operator !== \"=\") { this.raise(node.left.end, \"Only '=' operator can be used for specifying default value.\"); }\n node.type = \"AssignmentPattern\";\n delete node.operator;\n this.toAssignable(node.left, isBinding);\n break\n\n case \"ParenthesizedExpression\":\n this.toAssignable(node.expression, isBinding, refDestructuringErrors);\n break\n\n case \"ChainExpression\":\n this.raiseRecoverable(node.start, \"Optional chaining cannot appear in left-hand side\");\n break\n\n case \"MemberExpression\":\n if (!isBinding) { break }\n\n default:\n this.raise(node.start, \"Assigning to rvalue\");\n }\n } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n return node\n};\n\n// Convert list of expression atoms to binding list.\n\npp$7.toAssignableList = function(exprList, isBinding) {\n var end = exprList.length;\n for (var i = 0; i < end; i++) {\n var elt = exprList[i];\n if (elt) { this.toAssignable(elt, isBinding); }\n }\n if (end) {\n var last = exprList[end - 1];\n if (this.options.ecmaVersion === 6 && isBinding && last && last.type === \"RestElement\" && last.argument.type !== \"Identifier\")\n { this.unexpected(last.argument.start); }\n }\n return exprList\n};\n\n// Parses spread element.\n\npp$7.parseSpread = function(refDestructuringErrors) {\n var node = this.startNode();\n this.next();\n node.argument = this.parseMaybeAssign(false, refDestructuringErrors);\n return this.finishNode(node, \"SpreadElement\")\n};\n\npp$7.parseRestBinding = function() {\n var node = this.startNode();\n this.next();\n\n // RestElement inside of a function parameter must be an identifier\n if (this.options.ecmaVersion === 6 && this.type !== types$1.name)\n { this.unexpected(); }\n\n node.argument = this.parseBindingAtom();\n\n return this.finishNode(node, \"RestElement\")\n};\n\n// Parses lvalue (assignable) atom.\n\npp$7.parseBindingAtom = function() {\n if (this.options.ecmaVersion >= 6) {\n switch (this.type) {\n case types$1.bracketL:\n var node = this.startNode();\n this.next();\n node.elements = this.parseBindingList(types$1.bracketR, true, true);\n return this.finishNode(node, \"ArrayPattern\")\n\n case types$1.braceL:\n return this.parseObj(true)\n }\n }\n return this.parseIdent()\n};\n\npp$7.parseBindingList = function(close, allowEmpty, allowTrailingComma) {\n var elts = [], first = true;\n while (!this.eat(close)) {\n if (first) { first = false; }\n else { this.expect(types$1.comma); }\n if (allowEmpty && this.type === types$1.comma) {\n elts.push(null);\n } else if (allowTrailingComma && this.afterTrailingComma(close)) {\n break\n } else if (this.type === types$1.ellipsis) {\n var rest = this.parseRestBinding();\n this.parseBindingListItem(rest);\n elts.push(rest);\n if (this.type === types$1.comma) { this.raise(this.start, \"Comma is not permitted after the rest element\"); }\n this.expect(close);\n break\n } else {\n var elem = this.parseMaybeDefault(this.start, this.startLoc);\n this.parseBindingListItem(elem);\n elts.push(elem);\n }\n }\n return elts\n};\n\npp$7.parseBindingListItem = function(param) {\n return param\n};\n\n// Parses assignment pattern around given atom if possible.\n\npp$7.parseMaybeDefault = function(startPos, startLoc, left) {\n left = left || this.parseBindingAtom();\n if (this.options.ecmaVersion < 6 || !this.eat(types$1.eq)) { return left }\n var node = this.startNodeAt(startPos, startLoc);\n node.left = left;\n node.right = this.parseMaybeAssign();\n return this.finishNode(node, \"AssignmentPattern\")\n};\n\n// The following three functions all verify that a node is an lvalue —\n// something that can be bound, or assigned to. In order to do so, they perform\n// a variety of checks:\n//\n// - Check that none of the bound/assigned-to identifiers are reserved words.\n// - Record name declarations for bindings in the appropriate scope.\n// - Check duplicate argument names, if checkClashes is set.\n//\n// If a complex binding pattern is encountered (e.g., object and array\n// destructuring), the entire pattern is recursively checked.\n//\n// There are three versions of checkLVal*() appropriate for different\n// circumstances:\n//\n// - checkLValSimple() shall be used if the syntactic construct supports\n// nothing other than identifiers and member expressions. Parenthesized\n// expressions are also correctly handled. This is generally appropriate for\n// constructs for which the spec says\n//\n// > It is a Syntax Error if AssignmentTargetType of [the production] is not\n// > simple.\n//\n// It is also appropriate for checking if an identifier is valid and not\n// defined elsewhere, like import declarations or function/class identifiers.\n//\n// Examples where this is used include:\n// a += …;\n// import a from '…';\n// where a is the node to be checked.\n//\n// - checkLValPattern() shall be used if the syntactic construct supports\n// anything checkLValSimple() supports, as well as object and array\n// destructuring patterns. This is generally appropriate for constructs for\n// which the spec says\n//\n// > It is a Syntax Error if [the production] is neither an ObjectLiteral nor\n// > an ArrayLiteral and AssignmentTargetType of [the production] is not\n// > simple.\n//\n// Examples where this is used include:\n// (a = …);\n// const a = …;\n// try { … } catch (a) { … }\n// where a is the node to be checked.\n//\n// - checkLValInnerPattern() shall be used if the syntactic construct supports\n// anything checkLValPattern() supports, as well as default assignment\n// patterns, rest elements, and other constructs that may appear within an\n// object or array destructuring pattern.\n//\n// As a special case, function parameters also use checkLValInnerPattern(),\n// as they also support defaults and rest constructs.\n//\n// These functions deliberately support both assignment and binding constructs,\n// as the logic for both is exceedingly similar. If the node is the target of\n// an assignment, then bindingType should be set to BIND_NONE. Otherwise, it\n// should be set to the appropriate BIND_* constant, like BIND_VAR or\n// BIND_LEXICAL.\n//\n// If the function is called with a non-BIND_NONE bindingType, then\n// additionally a checkClashes object may be specified to allow checking for\n// duplicate argument names. checkClashes is ignored if the provided construct\n// is an assignment (i.e., bindingType is BIND_NONE).\n\npp$7.checkLValSimple = function(expr, bindingType, checkClashes) {\n if ( bindingType === void 0 ) bindingType = BIND_NONE;\n\n var isBind = bindingType !== BIND_NONE;\n\n switch (expr.type) {\n case \"Identifier\":\n if (this.strict && this.reservedWordsStrictBind.test(expr.name))\n { this.raiseRecoverable(expr.start, (isBind ? \"Binding \" : \"Assigning to \") + expr.name + \" in strict mode\"); }\n if (isBind) {\n if (bindingType === BIND_LEXICAL && expr.name === \"let\")\n { this.raiseRecoverable(expr.start, \"let is disallowed as a lexically bound name\"); }\n if (checkClashes) {\n if (hasOwn(checkClashes, expr.name))\n { this.raiseRecoverable(expr.start, \"Argument name clash\"); }\n checkClashes[expr.name] = true;\n }\n if (bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); }\n }\n break\n\n case \"ChainExpression\":\n this.raiseRecoverable(expr.start, \"Optional chaining cannot appear in left-hand side\");\n break\n\n case \"MemberExpression\":\n if (isBind) { this.raiseRecoverable(expr.start, \"Binding member expression\"); }\n break\n\n case \"ParenthesizedExpression\":\n if (isBind) { this.raiseRecoverable(expr.start, \"Binding parenthesized expression\"); }\n return this.checkLValSimple(expr.expression, bindingType, checkClashes)\n\n default:\n this.raise(expr.start, (isBind ? \"Binding\" : \"Assigning to\") + \" rvalue\");\n }\n};\n\npp$7.checkLValPattern = function(expr, bindingType, checkClashes) {\n if ( bindingType === void 0 ) bindingType = BIND_NONE;\n\n switch (expr.type) {\n case \"ObjectPattern\":\n for (var i = 0, list = expr.properties; i < list.length; i += 1) {\n var prop = list[i];\n\n this.checkLValInnerPattern(prop, bindingType, checkClashes);\n }\n break\n\n case \"ArrayPattern\":\n for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {\n var elem = list$1[i$1];\n\n if (elem) { this.checkLValInnerPattern(elem, bindingType, checkClashes); }\n }\n break\n\n default:\n this.checkLValSimple(expr, bindingType, checkClashes);\n }\n};\n\npp$7.checkLValInnerPattern = function(expr, bindingType, checkClashes) {\n if ( bindingType === void 0 ) bindingType = BIND_NONE;\n\n switch (expr.type) {\n case \"Property\":\n // AssignmentProperty has type === \"Property\"\n this.checkLValInnerPattern(expr.value, bindingType, checkClashes);\n break\n\n case \"AssignmentPattern\":\n this.checkLValPattern(expr.left, bindingType, checkClashes);\n break\n\n case \"RestElement\":\n this.checkLValPattern(expr.argument, bindingType, checkClashes);\n break\n\n default:\n this.checkLValPattern(expr, bindingType, checkClashes);\n }\n};\n\n// The algorithm used to determine whether a regexp can appear at a\n\nvar TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {\n this.token = token;\n this.isExpr = !!isExpr;\n this.preserveSpace = !!preserveSpace;\n this.override = override;\n this.generator = !!generator;\n};\n\nvar types = {\n b_stat: new TokContext(\"{\", false),\n b_expr: new TokContext(\"{\", true),\n b_tmpl: new TokContext(\"${\", false),\n p_stat: new TokContext(\"(\", false),\n p_expr: new TokContext(\"(\", true),\n q_tmpl: new TokContext(\"`\", true, true, function (p) { return p.tryReadTemplateToken(); }),\n f_stat: new TokContext(\"function\", false),\n f_expr: new TokContext(\"function\", true),\n f_expr_gen: new TokContext(\"function\", true, false, null, true),\n f_gen: new TokContext(\"function\", false, false, null, true)\n};\n\nvar pp$6 = Parser.prototype;\n\npp$6.initialContext = function() {\n return [types.b_stat]\n};\n\npp$6.curContext = function() {\n return this.context[this.context.length - 1]\n};\n\npp$6.braceIsBlock = function(prevType) {\n var parent = this.curContext();\n if (parent === types.f_expr || parent === types.f_stat)\n { return true }\n if (prevType === types$1.colon && (parent === types.b_stat || parent === types.b_expr))\n { return !parent.isExpr }\n\n // The check for `tt.name && exprAllowed` detects whether we are\n // after a `yield` or `of` construct. See the `updateContext` for\n // `tt.name`.\n if (prevType === types$1._return || prevType === types$1.name && this.exprAllowed)\n { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }\n if (prevType === types$1._else || prevType === types$1.semi || prevType === types$1.eof || prevType === types$1.parenR || prevType === types$1.arrow)\n { return true }\n if (prevType === types$1.braceL)\n { return parent === types.b_stat }\n if (prevType === types$1._var || prevType === types$1._const || prevType === types$1.name)\n { return false }\n return !this.exprAllowed\n};\n\npp$6.inGeneratorContext = function() {\n for (var i = this.context.length - 1; i >= 1; i--) {\n var context = this.context[i];\n if (context.token === \"function\")\n { return context.generator }\n }\n return false\n};\n\npp$6.updateContext = function(prevType) {\n var update, type = this.type;\n if (type.keyword && prevType === types$1.dot)\n { this.exprAllowed = false; }\n else if (update = type.updateContext)\n { update.call(this, prevType); }\n else\n { this.exprAllowed = type.beforeExpr; }\n};\n\n// Used to handle egde cases when token context could not be inferred correctly during tokenization phase\n\npp$6.overrideContext = function(tokenCtx) {\n if (this.curContext() !== tokenCtx) {\n this.context[this.context.length - 1] = tokenCtx;\n }\n};\n\n// Token-specific context update code\n\ntypes$1.parenR.updateContext = types$1.braceR.updateContext = function() {\n if (this.context.length === 1) {\n this.exprAllowed = true;\n return\n }\n var out = this.context.pop();\n if (out === types.b_stat && this.curContext().token === \"function\") {\n out = this.context.pop();\n }\n this.exprAllowed = !out.isExpr;\n};\n\ntypes$1.braceL.updateContext = function(prevType) {\n this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr);\n this.exprAllowed = true;\n};\n\ntypes$1.dollarBraceL.updateContext = function() {\n this.context.push(types.b_tmpl);\n this.exprAllowed = true;\n};\n\ntypes$1.parenL.updateContext = function(prevType) {\n var statementParens = prevType === types$1._if || prevType === types$1._for || prevType === types$1._with || prevType === types$1._while;\n this.context.push(statementParens ? types.p_stat : types.p_expr);\n this.exprAllowed = true;\n};\n\ntypes$1.incDec.updateContext = function() {\n // tokExprAllowed stays unchanged\n};\n\ntypes$1._function.updateContext = types$1._class.updateContext = function(prevType) {\n if (prevType.beforeExpr && prevType !== types$1._else &&\n !(prevType === types$1.semi && this.curContext() !== types.p_stat) &&\n !(prevType === types$1._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) &&\n !((prevType === types$1.colon || prevType === types$1.braceL) && this.curContext() === types.b_stat))\n { this.context.push(types.f_expr); }\n else\n { this.context.push(types.f_stat); }\n this.exprAllowed = false;\n};\n\ntypes$1.backQuote.updateContext = function() {\n if (this.curContext() === types.q_tmpl)\n { this.context.pop(); }\n else\n { this.context.push(types.q_tmpl); }\n this.exprAllowed = false;\n};\n\ntypes$1.star.updateContext = function(prevType) {\n if (prevType === types$1._function) {\n var index = this.context.length - 1;\n if (this.context[index] === types.f_expr)\n { this.context[index] = types.f_expr_gen; }\n else\n { this.context[index] = types.f_gen; }\n }\n this.exprAllowed = true;\n};\n\ntypes$1.name.updateContext = function(prevType) {\n var allowed = false;\n if (this.options.ecmaVersion >= 6 && prevType !== types$1.dot) {\n if (this.value === \"of\" && !this.exprAllowed ||\n this.value === \"yield\" && this.inGeneratorContext())\n { allowed = true; }\n }\n this.exprAllowed = allowed;\n};\n\n// A recursive descent parser operates by defining functions for all\n\nvar pp$5 = Parser.prototype;\n\n// Check if property name clashes with already added.\n// Object/class getters and setters are not allowed to clash —\n// either with each other or with an init property — and in\n// strict mode, init properties are also not allowed to be repeated.\n\npp$5.checkPropClash = function(prop, propHash, refDestructuringErrors) {\n if (this.options.ecmaVersion >= 9 && prop.type === \"SpreadElement\")\n { return }\n if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))\n { return }\n var key = prop.key;\n var name;\n switch (key.type) {\n case \"Identifier\": name = key.name; break\n case \"Literal\": name = String(key.value); break\n default: return\n }\n var kind = prop.kind;\n if (this.options.ecmaVersion >= 6) {\n if (name === \"__proto__\" && kind === \"init\") {\n if (propHash.proto) {\n if (refDestructuringErrors) {\n if (refDestructuringErrors.doubleProto < 0) {\n refDestructuringErrors.doubleProto = key.start;\n }\n } else {\n this.raiseRecoverable(key.start, \"Redefinition of __proto__ property\");\n }\n }\n propHash.proto = true;\n }\n return\n }\n name = \"$\" + name;\n var other = propHash[name];\n if (other) {\n var redefinition;\n if (kind === \"init\") {\n redefinition = this.strict && other.init || other.get || other.set;\n } else {\n redefinition = other.init || other[kind];\n }\n if (redefinition)\n { this.raiseRecoverable(key.start, \"Redefinition of property\"); }\n } else {\n other = propHash[name] = {\n init: false,\n get: false,\n set: false\n };\n }\n other[kind] = true;\n};\n\n// ### Expression parsing\n\n// These nest, from the most general expression type at the top to\n// 'atomic', nondivisible expression types at the bottom. Most of\n// the functions will simply let the function(s) below them parse,\n// and, *if* the syntactic construct they handle is present, wrap\n// the AST node that the inner parser gave them in another node.\n\n// Parse a full expression. The optional arguments are used to\n// forbid the `in` operator (in for loops initalization expressions)\n// and provide reference for storing '=' operator inside shorthand\n// property assignment in contexts where both object expression\n// and object pattern might appear (so it's possible to raise\n// delayed syntax error at correct position).\n\npp$5.parseExpression = function(forInit, refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseMaybeAssign(forInit, refDestructuringErrors);\n if (this.type === types$1.comma) {\n var node = this.startNodeAt(startPos, startLoc);\n node.expressions = [expr];\n while (this.eat(types$1.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); }\n return this.finishNode(node, \"SequenceExpression\")\n }\n return expr\n};\n\n// Parse an assignment expression. This includes applications of\n// operators like `+=`.\n\npp$5.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) {\n if (this.isContextual(\"yield\")) {\n if (this.inGenerator) { return this.parseYield(forInit) }\n // The tokenizer will assume an expression is allowed after\n // `yield`, but this isn't that kind of yield\n else { this.exprAllowed = false; }\n }\n\n var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldDoubleProto = -1;\n if (refDestructuringErrors) {\n oldParenAssign = refDestructuringErrors.parenthesizedAssign;\n oldTrailingComma = refDestructuringErrors.trailingComma;\n oldDoubleProto = refDestructuringErrors.doubleProto;\n refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;\n } else {\n refDestructuringErrors = new DestructuringErrors;\n ownDestructuringErrors = true;\n }\n\n var startPos = this.start, startLoc = this.startLoc;\n if (this.type === types$1.parenL || this.type === types$1.name) {\n this.potentialArrowAt = this.start;\n this.potentialArrowInForAwait = forInit === \"await\";\n }\n var left = this.parseMaybeConditional(forInit, refDestructuringErrors);\n if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }\n if (this.type.isAssign) {\n var node = this.startNodeAt(startPos, startLoc);\n node.operator = this.value;\n if (this.type === types$1.eq)\n { left = this.toAssignable(left, false, refDestructuringErrors); }\n if (!ownDestructuringErrors) {\n refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1;\n }\n if (refDestructuringErrors.shorthandAssign >= left.start)\n { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly\n if (this.type === types$1.eq)\n { this.checkLValPattern(left); }\n else\n { this.checkLValSimple(left); }\n node.left = left;\n this.next();\n node.right = this.parseMaybeAssign(forInit);\n if (oldDoubleProto > -1) { refDestructuringErrors.doubleProto = oldDoubleProto; }\n return this.finishNode(node, \"AssignmentExpression\")\n } else {\n if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }\n }\n if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }\n if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }\n return left\n};\n\n// Parse a ternary conditional (`?:`) operator.\n\npp$5.parseMaybeConditional = function(forInit, refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseExprOps(forInit, refDestructuringErrors);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n if (this.eat(types$1.question)) {\n var node = this.startNodeAt(startPos, startLoc);\n node.test = expr;\n node.consequent = this.parseMaybeAssign();\n this.expect(types$1.colon);\n node.alternate = this.parseMaybeAssign(forInit);\n return this.finishNode(node, \"ConditionalExpression\")\n }\n return expr\n};\n\n// Start the precedence parser.\n\npp$5.parseExprOps = function(forInit, refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseMaybeUnary(refDestructuringErrors, false, false, forInit);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n return expr.start === startPos && expr.type === \"ArrowFunctionExpression\" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit)\n};\n\n// Parse binary operators with the operator precedence parsing\n// algorithm. `left` is the left-hand side of the operator.\n// `minPrec` provides context that allows the function to stop and\n// defer further parser to one of its callers when it encounters an\n// operator that has a lower precedence than the set it is parsing.\n\npp$5.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) {\n var prec = this.type.binop;\n if (prec != null && (!forInit || this.type !== types$1._in)) {\n if (prec > minPrec) {\n var logical = this.type === types$1.logicalOR || this.type === types$1.logicalAND;\n var coalesce = this.type === types$1.coalesce;\n if (coalesce) {\n // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions.\n // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error.\n prec = types$1.logicalAND.binop;\n }\n var op = this.value;\n this.next();\n var startPos = this.start, startLoc = this.startLoc;\n var right = this.parseExprOp(this.parseMaybeUnary(null, false, false, forInit), startPos, startLoc, prec, forInit);\n var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce);\n if ((logical && this.type === types$1.coalesce) || (coalesce && (this.type === types$1.logicalOR || this.type === types$1.logicalAND))) {\n this.raiseRecoverable(this.start, \"Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses\");\n }\n return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit)\n }\n }\n return left\n};\n\npp$5.buildBinary = function(startPos, startLoc, left, right, op, logical) {\n if (right.type === \"PrivateIdentifier\") { this.raise(right.start, \"Private identifier can only be left side of binary expression\"); }\n var node = this.startNodeAt(startPos, startLoc);\n node.left = left;\n node.operator = op;\n node.right = right;\n return this.finishNode(node, logical ? \"LogicalExpression\" : \"BinaryExpression\")\n};\n\n// Parse unary operators, both prefix and postfix.\n\npp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forInit) {\n var startPos = this.start, startLoc = this.startLoc, expr;\n if (this.isContextual(\"await\") && this.canAwait) {\n expr = this.parseAwait(forInit);\n sawUnary = true;\n } else if (this.type.prefix) {\n var node = this.startNode(), update = this.type === types$1.incDec;\n node.operator = this.value;\n node.prefix = true;\n this.next();\n node.argument = this.parseMaybeUnary(null, true, update, forInit);\n this.checkExpressionErrors(refDestructuringErrors, true);\n if (update) { this.checkLValSimple(node.argument); }\n else if (this.strict && node.operator === \"delete\" &&\n node.argument.type === \"Identifier\")\n { this.raiseRecoverable(node.start, \"Deleting local variable in strict mode\"); }\n else if (node.operator === \"delete\" && isPrivateFieldAccess(node.argument))\n { this.raiseRecoverable(node.start, \"Private fields can not be deleted\"); }\n else { sawUnary = true; }\n expr = this.finishNode(node, update ? \"UpdateExpression\" : \"UnaryExpression\");\n } else if (!sawUnary && this.type === types$1.privateId) {\n if (forInit || this.privateNameStack.length === 0) { this.unexpected(); }\n expr = this.parsePrivateIdent();\n // only could be private fields in 'in', such as #x in obj\n if (this.type !== types$1._in) { this.unexpected(); }\n } else {\n expr = this.parseExprSubscripts(refDestructuringErrors, forInit);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n while (this.type.postfix && !this.canInsertSemicolon()) {\n var node$1 = this.startNodeAt(startPos, startLoc);\n node$1.operator = this.value;\n node$1.prefix = false;\n node$1.argument = expr;\n this.checkLValSimple(expr);\n this.next();\n expr = this.finishNode(node$1, \"UpdateExpression\");\n }\n }\n\n if (!incDec && this.eat(types$1.starstar)) {\n if (sawUnary)\n { this.unexpected(this.lastTokStart); }\n else\n { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false, false, forInit), \"**\", false) }\n } else {\n return expr\n }\n};\n\nfunction isPrivateFieldAccess(node) {\n return (\n node.type === \"MemberExpression\" && node.property.type === \"PrivateIdentifier\" ||\n node.type === \"ChainExpression\" && isPrivateFieldAccess(node.expression)\n )\n}\n\n// Parse call, dot, and `[]`-subscript expressions.\n\npp$5.parseExprSubscripts = function(refDestructuringErrors, forInit) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseExprAtom(refDestructuringErrors, forInit);\n if (expr.type === \"ArrowFunctionExpression\" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== \")\")\n { return expr }\n var result = this.parseSubscripts(expr, startPos, startLoc, false, forInit);\n if (refDestructuringErrors && result.type === \"MemberExpression\") {\n if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }\n if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }\n if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; }\n }\n return result\n};\n\npp$5.parseSubscripts = function(base, startPos, startLoc, noCalls, forInit) {\n var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === \"Identifier\" && base.name === \"async\" &&\n this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 &&\n this.potentialArrowAt === base.start;\n var optionalChained = false;\n\n while (true) {\n var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit);\n\n if (element.optional) { optionalChained = true; }\n if (element === base || element.type === \"ArrowFunctionExpression\") {\n if (optionalChained) {\n var chainNode = this.startNodeAt(startPos, startLoc);\n chainNode.expression = element;\n element = this.finishNode(chainNode, \"ChainExpression\");\n }\n return element\n }\n\n base = element;\n }\n};\n\npp$5.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) {\n var optionalSupported = this.options.ecmaVersion >= 11;\n var optional = optionalSupported && this.eat(types$1.questionDot);\n if (noCalls && optional) { this.raise(this.lastTokStart, \"Optional chaining cannot appear in the callee of new expressions\"); }\n\n var computed = this.eat(types$1.bracketL);\n if (computed || (optional && this.type !== types$1.parenL && this.type !== types$1.backQuote) || this.eat(types$1.dot)) {\n var node = this.startNodeAt(startPos, startLoc);\n node.object = base;\n if (computed) {\n node.property = this.parseExpression();\n this.expect(types$1.bracketR);\n } else if (this.type === types$1.privateId && base.type !== \"Super\") {\n node.property = this.parsePrivateIdent();\n } else {\n node.property = this.parseIdent(this.options.allowReserved !== \"never\");\n }\n node.computed = !!computed;\n if (optionalSupported) {\n node.optional = optional;\n }\n base = this.finishNode(node, \"MemberExpression\");\n } else if (!noCalls && this.eat(types$1.parenL)) {\n var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.awaitIdentPos = 0;\n var exprList = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors);\n if (maybeAsyncArrow && !optional && !this.canInsertSemicolon() && this.eat(types$1.arrow)) {\n this.checkPatternErrors(refDestructuringErrors, false);\n this.checkYieldAwaitInDefaultParams();\n if (this.awaitIdentPos > 0)\n { this.raise(this.awaitIdentPos, \"Cannot use 'await' as identifier inside an async function\"); }\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.awaitIdentPos = oldAwaitIdentPos;\n return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true, forInit)\n }\n this.checkExpressionErrors(refDestructuringErrors, true);\n this.yieldPos = oldYieldPos || this.yieldPos;\n this.awaitPos = oldAwaitPos || this.awaitPos;\n this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos;\n var node$1 = this.startNodeAt(startPos, startLoc);\n node$1.callee = base;\n node$1.arguments = exprList;\n if (optionalSupported) {\n node$1.optional = optional;\n }\n base = this.finishNode(node$1, \"CallExpression\");\n } else if (this.type === types$1.backQuote) {\n if (optional || optionalChained) {\n this.raise(this.start, \"Optional chaining cannot appear in the tag of tagged template expressions\");\n }\n var node$2 = this.startNodeAt(startPos, startLoc);\n node$2.tag = base;\n node$2.quasi = this.parseTemplate({isTagged: true});\n base = this.finishNode(node$2, \"TaggedTemplateExpression\");\n }\n return base\n};\n\n// Parse an atomic expression — either a single token that is an\n// expression, an expression started by a keyword like `function` or\n// `new`, or an expression wrapped in punctuation like `()`, `[]`,\n// or `{}`.\n\npp$5.parseExprAtom = function(refDestructuringErrors, forInit) {\n // If a division operator appears in an expression position, the\n // tokenizer got confused, and we force it to read a regexp instead.\n if (this.type === types$1.slash) { this.readRegexp(); }\n\n var node, canBeArrow = this.potentialArrowAt === this.start;\n switch (this.type) {\n case types$1._super:\n if (!this.allowSuper)\n { this.raise(this.start, \"'super' keyword outside a method\"); }\n node = this.startNode();\n this.next();\n if (this.type === types$1.parenL && !this.allowDirectSuper)\n { this.raise(node.start, \"super() call outside constructor of a subclass\"); }\n // The `super` keyword can appear at below:\n // SuperProperty:\n // super [ Expression ]\n // super . IdentifierName\n // SuperCall:\n // super ( Arguments )\n if (this.type !== types$1.dot && this.type !== types$1.bracketL && this.type !== types$1.parenL)\n { this.unexpected(); }\n return this.finishNode(node, \"Super\")\n\n case types$1._this:\n node = this.startNode();\n this.next();\n return this.finishNode(node, \"ThisExpression\")\n\n case types$1.name:\n var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;\n var id = this.parseIdent(false);\n if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === \"async\" && !this.canInsertSemicolon() && this.eat(types$1._function)) {\n this.overrideContext(types.f_expr);\n return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true, forInit)\n }\n if (canBeArrow && !this.canInsertSemicolon()) {\n if (this.eat(types$1.arrow))\n { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false, forInit) }\n if (this.options.ecmaVersion >= 8 && id.name === \"async\" && this.type === types$1.name && !containsEsc &&\n (!this.potentialArrowInForAwait || this.value !== \"of\" || this.containsEsc)) {\n id = this.parseIdent(false);\n if (this.canInsertSemicolon() || !this.eat(types$1.arrow))\n { this.unexpected(); }\n return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true, forInit)\n }\n }\n return id\n\n case types$1.regexp:\n var value = this.value;\n node = this.parseLiteral(value.value);\n node.regex = {pattern: value.pattern, flags: value.flags};\n return node\n\n case types$1.num: case types$1.string:\n return this.parseLiteral(this.value)\n\n case types$1._null: case types$1._true: case types$1._false:\n node = this.startNode();\n node.value = this.type === types$1._null ? null : this.type === types$1._true;\n node.raw = this.type.keyword;\n this.next();\n return this.finishNode(node, \"Literal\")\n\n case types$1.parenL:\n var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow, forInit);\n if (refDestructuringErrors) {\n if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))\n { refDestructuringErrors.parenthesizedAssign = start; }\n if (refDestructuringErrors.parenthesizedBind < 0)\n { refDestructuringErrors.parenthesizedBind = start; }\n }\n return expr\n\n case types$1.bracketL:\n node = this.startNode();\n this.next();\n node.elements = this.parseExprList(types$1.bracketR, true, true, refDestructuringErrors);\n return this.finishNode(node, \"ArrayExpression\")\n\n case types$1.braceL:\n this.overrideContext(types.b_expr);\n return this.parseObj(false, refDestructuringErrors)\n\n case types$1._function:\n node = this.startNode();\n this.next();\n return this.parseFunction(node, 0)\n\n case types$1._class:\n return this.parseClass(this.startNode(), false)\n\n case types$1._new:\n return this.parseNew()\n\n case types$1.backQuote:\n return this.parseTemplate()\n\n case types$1._import:\n if (this.options.ecmaVersion >= 11) {\n return this.parseExprImport()\n } else {\n return this.unexpected()\n }\n\n default:\n this.unexpected();\n }\n};\n\npp$5.parseExprImport = function() {\n var node = this.startNode();\n\n // Consume `import` as an identifier for `import.meta`.\n // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`.\n if (this.containsEsc) { this.raiseRecoverable(this.start, \"Escape sequence in keyword import\"); }\n var meta = this.parseIdent(true);\n\n switch (this.type) {\n case types$1.parenL:\n return this.parseDynamicImport(node)\n case types$1.dot:\n node.meta = meta;\n return this.parseImportMeta(node)\n default:\n this.unexpected();\n }\n};\n\npp$5.parseDynamicImport = function(node) {\n this.next(); // skip `(`\n\n // Parse node.source.\n node.source = this.parseMaybeAssign();\n\n // Verify ending.\n if (!this.eat(types$1.parenR)) {\n var errorPos = this.start;\n if (this.eat(types$1.comma) && this.eat(types$1.parenR)) {\n this.raiseRecoverable(errorPos, \"Trailing comma is not allowed in import()\");\n } else {\n this.unexpected(errorPos);\n }\n }\n\n return this.finishNode(node, \"ImportExpression\")\n};\n\npp$5.parseImportMeta = function(node) {\n this.next(); // skip `.`\n\n var containsEsc = this.containsEsc;\n node.property = this.parseIdent(true);\n\n if (node.property.name !== \"meta\")\n { this.raiseRecoverable(node.property.start, \"The only valid meta property for import is 'import.meta'\"); }\n if (containsEsc)\n { this.raiseRecoverable(node.start, \"'import.meta' must not contain escaped characters\"); }\n if (this.options.sourceType !== \"module\" && !this.options.allowImportExportEverywhere)\n { this.raiseRecoverable(node.start, \"Cannot use 'import.meta' outside a module\"); }\n\n return this.finishNode(node, \"MetaProperty\")\n};\n\npp$5.parseLiteral = function(value) {\n var node = this.startNode();\n node.value = value;\n node.raw = this.input.slice(this.start, this.end);\n if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1).replace(/_/g, \"\"); }\n this.next();\n return this.finishNode(node, \"Literal\")\n};\n\npp$5.parseParenExpression = function() {\n this.expect(types$1.parenL);\n var val = this.parseExpression();\n this.expect(types$1.parenR);\n return val\n};\n\npp$5.parseParenAndDistinguishExpression = function(canBeArrow, forInit) {\n var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;\n if (this.options.ecmaVersion >= 6) {\n this.next();\n\n var innerStartPos = this.start, innerStartLoc = this.startLoc;\n var exprList = [], first = true, lastIsComma = false;\n var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;\n this.yieldPos = 0;\n this.awaitPos = 0;\n // Do not save awaitIdentPos to allow checking awaits nested in parameters\n while (this.type !== types$1.parenR) {\n first ? first = false : this.expect(types$1.comma);\n if (allowTrailingComma && this.afterTrailingComma(types$1.parenR, true)) {\n lastIsComma = true;\n break\n } else if (this.type === types$1.ellipsis) {\n spreadStart = this.start;\n exprList.push(this.parseParenItem(this.parseRestBinding()));\n if (this.type === types$1.comma) { this.raise(this.start, \"Comma is not permitted after the rest element\"); }\n break\n } else {\n exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem));\n }\n }\n var innerEndPos = this.lastTokEnd, innerEndLoc = this.lastTokEndLoc;\n this.expect(types$1.parenR);\n\n if (canBeArrow && !this.canInsertSemicolon() && this.eat(types$1.arrow)) {\n this.checkPatternErrors(refDestructuringErrors, false);\n this.checkYieldAwaitInDefaultParams();\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n return this.parseParenArrowList(startPos, startLoc, exprList, forInit)\n }\n\n if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }\n if (spreadStart) { this.unexpected(spreadStart); }\n this.checkExpressionErrors(refDestructuringErrors, true);\n this.yieldPos = oldYieldPos || this.yieldPos;\n this.awaitPos = oldAwaitPos || this.awaitPos;\n\n if (exprList.length > 1) {\n val = this.startNodeAt(innerStartPos, innerStartLoc);\n val.expressions = exprList;\n this.finishNodeAt(val, \"SequenceExpression\", innerEndPos, innerEndLoc);\n } else {\n val = exprList[0];\n }\n } else {\n val = this.parseParenExpression();\n }\n\n if (this.options.preserveParens) {\n var par = this.startNodeAt(startPos, startLoc);\n par.expression = val;\n return this.finishNode(par, \"ParenthesizedExpression\")\n } else {\n return val\n }\n};\n\npp$5.parseParenItem = function(item) {\n return item\n};\n\npp$5.parseParenArrowList = function(startPos, startLoc, exprList, forInit) {\n return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, false, forInit)\n};\n\n// New's precedence is slightly tricky. It must allow its argument to\n// be a `[]` or dot subscript expression, but not a call — at least,\n// not without wrapping it in parentheses. Thus, it uses the noCalls\n// argument to parseSubscripts to prevent it from consuming the\n// argument list.\n\nvar empty = [];\n\npp$5.parseNew = function() {\n if (this.containsEsc) { this.raiseRecoverable(this.start, \"Escape sequence in keyword new\"); }\n var node = this.startNode();\n var meta = this.parseIdent(true);\n if (this.options.ecmaVersion >= 6 && this.eat(types$1.dot)) {\n node.meta = meta;\n var containsEsc = this.containsEsc;\n node.property = this.parseIdent(true);\n if (node.property.name !== \"target\")\n { this.raiseRecoverable(node.property.start, \"The only valid meta property for new is 'new.target'\"); }\n if (containsEsc)\n { this.raiseRecoverable(node.start, \"'new.target' must not contain escaped characters\"); }\n if (!this.allowNewDotTarget)\n { this.raiseRecoverable(node.start, \"'new.target' can only be used in functions and class static block\"); }\n return this.finishNode(node, \"MetaProperty\")\n }\n var startPos = this.start, startLoc = this.startLoc, isImport = this.type === types$1._import;\n node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true, false);\n if (isImport && node.callee.type === \"ImportExpression\") {\n this.raise(startPos, \"Cannot use new with import()\");\n }\n if (this.eat(types$1.parenL)) { node.arguments = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false); }\n else { node.arguments = empty; }\n return this.finishNode(node, \"NewExpression\")\n};\n\n// Parse template expression.\n\npp$5.parseTemplateElement = function(ref) {\n var isTagged = ref.isTagged;\n\n var elem = this.startNode();\n if (this.type === types$1.invalidTemplate) {\n if (!isTagged) {\n this.raiseRecoverable(this.start, \"Bad escape sequence in untagged template literal\");\n }\n elem.value = {\n raw: this.value,\n cooked: null\n };\n } else {\n elem.value = {\n raw: this.input.slice(this.start, this.end).replace(/\\r\\n?/g, \"\\n\"),\n cooked: this.value\n };\n }\n this.next();\n elem.tail = this.type === types$1.backQuote;\n return this.finishNode(elem, \"TemplateElement\")\n};\n\npp$5.parseTemplate = function(ref) {\n if ( ref === void 0 ) ref = {};\n var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;\n\n var node = this.startNode();\n this.next();\n node.expressions = [];\n var curElt = this.parseTemplateElement({isTagged: isTagged});\n node.quasis = [curElt];\n while (!curElt.tail) {\n if (this.type === types$1.eof) { this.raise(this.pos, \"Unterminated template literal\"); }\n this.expect(types$1.dollarBraceL);\n node.expressions.push(this.parseExpression());\n this.expect(types$1.braceR);\n node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged}));\n }\n this.next();\n return this.finishNode(node, \"TemplateLiteral\")\n};\n\npp$5.isAsyncProp = function(prop) {\n return !prop.computed && prop.key.type === \"Identifier\" && prop.key.name === \"async\" &&\n (this.type === types$1.name || this.type === types$1.num || this.type === types$1.string || this.type === types$1.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types$1.star)) &&\n !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))\n};\n\n// Parse an object literal or binding pattern.\n\npp$5.parseObj = function(isPattern, refDestructuringErrors) {\n var node = this.startNode(), first = true, propHash = {};\n node.properties = [];\n this.next();\n while (!this.eat(types$1.braceR)) {\n if (!first) {\n this.expect(types$1.comma);\n if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types$1.braceR)) { break }\n } else { first = false; }\n\n var prop = this.parseProperty(isPattern, refDestructuringErrors);\n if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); }\n node.properties.push(prop);\n }\n return this.finishNode(node, isPattern ? \"ObjectPattern\" : \"ObjectExpression\")\n};\n\npp$5.parseProperty = function(isPattern, refDestructuringErrors) {\n var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;\n if (this.options.ecmaVersion >= 9 && this.eat(types$1.ellipsis)) {\n if (isPattern) {\n prop.argument = this.parseIdent(false);\n if (this.type === types$1.comma) {\n this.raise(this.start, \"Comma is not permitted after the rest element\");\n }\n return this.finishNode(prop, \"RestElement\")\n }\n // Parse argument.\n prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);\n // To disallow trailing comma via `this.toAssignable()`.\n if (this.type === types$1.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {\n refDestructuringErrors.trailingComma = this.start;\n }\n // Finish\n return this.finishNode(prop, \"SpreadElement\")\n }\n if (this.options.ecmaVersion >= 6) {\n prop.method = false;\n prop.shorthand = false;\n if (isPattern || refDestructuringErrors) {\n startPos = this.start;\n startLoc = this.startLoc;\n }\n if (!isPattern)\n { isGenerator = this.eat(types$1.star); }\n }\n var containsEsc = this.containsEsc;\n this.parsePropertyName(prop);\n if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {\n isAsync = true;\n isGenerator = this.options.ecmaVersion >= 9 && this.eat(types$1.star);\n this.parsePropertyName(prop);\n } else {\n isAsync = false;\n }\n this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);\n return this.finishNode(prop, \"Property\")\n};\n\npp$5.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {\n if ((isGenerator || isAsync) && this.type === types$1.colon)\n { this.unexpected(); }\n\n if (this.eat(types$1.colon)) {\n prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);\n prop.kind = \"init\";\n } else if (this.options.ecmaVersion >= 6 && this.type === types$1.parenL) {\n if (isPattern) { this.unexpected(); }\n prop.kind = \"init\";\n prop.method = true;\n prop.value = this.parseMethod(isGenerator, isAsync);\n } else if (!isPattern && !containsEsc &&\n this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === \"Identifier\" &&\n (prop.key.name === \"get\" || prop.key.name === \"set\") &&\n (this.type !== types$1.comma && this.type !== types$1.braceR && this.type !== types$1.eq)) {\n if (isGenerator || isAsync) { this.unexpected(); }\n prop.kind = prop.key.name;\n this.parsePropertyName(prop);\n prop.value = this.parseMethod(false);\n var paramCount = prop.kind === \"get\" ? 0 : 1;\n if (prop.value.params.length !== paramCount) {\n var start = prop.value.start;\n if (prop.kind === \"get\")\n { this.raiseRecoverable(start, \"getter should have no params\"); }\n else\n { this.raiseRecoverable(start, \"setter should have exactly one param\"); }\n } else {\n if (prop.kind === \"set\" && prop.value.params[0].type === \"RestElement\")\n { this.raiseRecoverable(prop.value.params[0].start, \"Setter cannot use rest params\"); }\n }\n } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === \"Identifier\") {\n if (isGenerator || isAsync) { this.unexpected(); }\n this.checkUnreserved(prop.key);\n if (prop.key.name === \"await\" && !this.awaitIdentPos)\n { this.awaitIdentPos = startPos; }\n prop.kind = \"init\";\n if (isPattern) {\n prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key));\n } else if (this.type === types$1.eq && refDestructuringErrors) {\n if (refDestructuringErrors.shorthandAssign < 0)\n { refDestructuringErrors.shorthandAssign = this.start; }\n prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key));\n } else {\n prop.value = this.copyNode(prop.key);\n }\n prop.shorthand = true;\n } else { this.unexpected(); }\n};\n\npp$5.parsePropertyName = function(prop) {\n if (this.options.ecmaVersion >= 6) {\n if (this.eat(types$1.bracketL)) {\n prop.computed = true;\n prop.key = this.parseMaybeAssign();\n this.expect(types$1.bracketR);\n return prop.key\n } else {\n prop.computed = false;\n }\n }\n return prop.key = this.type === types$1.num || this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== \"never\")\n};\n\n// Initialize empty function node.\n\npp$5.initFunction = function(node) {\n node.id = null;\n if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; }\n if (this.options.ecmaVersion >= 8) { node.async = false; }\n};\n\n// Parse object or class method.\n\npp$5.parseMethod = function(isGenerator, isAsync, allowDirectSuper) {\n var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;\n\n this.initFunction(node);\n if (this.options.ecmaVersion >= 6)\n { node.generator = isGenerator; }\n if (this.options.ecmaVersion >= 8)\n { node.async = !!isAsync; }\n\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.awaitIdentPos = 0;\n this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0));\n\n this.expect(types$1.parenL);\n node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8);\n this.checkYieldAwaitInDefaultParams();\n this.parseFunctionBody(node, false, true, false);\n\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.awaitIdentPos = oldAwaitIdentPos;\n return this.finishNode(node, \"FunctionExpression\")\n};\n\n// Parse arrow function expression with given parameters.\n\npp$5.parseArrowExpression = function(node, params, isAsync, forInit) {\n var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;\n\n this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW);\n this.initFunction(node);\n if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; }\n\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.awaitIdentPos = 0;\n\n node.params = this.toAssignableList(params, true);\n this.parseFunctionBody(node, true, false, forInit);\n\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.awaitIdentPos = oldAwaitIdentPos;\n return this.finishNode(node, \"ArrowFunctionExpression\")\n};\n\n// Parse function body and check parameters.\n\npp$5.parseFunctionBody = function(node, isArrowFunction, isMethod, forInit) {\n var isExpression = isArrowFunction && this.type !== types$1.braceL;\n var oldStrict = this.strict, useStrict = false;\n\n if (isExpression) {\n node.body = this.parseMaybeAssign(forInit);\n node.expression = true;\n this.checkParams(node, false);\n } else {\n var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);\n if (!oldStrict || nonSimple) {\n useStrict = this.strictDirective(this.end);\n // If this is a strict mode function, verify that argument names\n // are not repeated, and it does not try to bind the words `eval`\n // or `arguments`.\n if (useStrict && nonSimple)\n { this.raiseRecoverable(node.start, \"Illegal 'use strict' directive in function with non-simple parameter list\"); }\n }\n // Start a new scope with regard to labels and the `inFunction`\n // flag (restore them to their old value afterwards).\n var oldLabels = this.labels;\n this.labels = [];\n if (useStrict) { this.strict = true; }\n\n // Add the params to varDeclaredNames to ensure that an error is thrown\n // if a let/const declaration in the function clashes with one of the params.\n this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params));\n // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'\n if (this.strict && node.id) { this.checkLValSimple(node.id, BIND_OUTSIDE); }\n node.body = this.parseBlock(false, undefined, useStrict && !oldStrict);\n node.expression = false;\n this.adaptDirectivePrologue(node.body.body);\n this.labels = oldLabels;\n }\n this.exitScope();\n};\n\npp$5.isSimpleParamList = function(params) {\n for (var i = 0, list = params; i < list.length; i += 1)\n {\n var param = list[i];\n\n if (param.type !== \"Identifier\") { return false\n } }\n return true\n};\n\n// Checks function params for various disallowed patterns such as using \"eval\"\n// or \"arguments\" and duplicate parameters.\n\npp$5.checkParams = function(node, allowDuplicates) {\n var nameHash = Object.create(null);\n for (var i = 0, list = node.params; i < list.length; i += 1)\n {\n var param = list[i];\n\n this.checkLValInnerPattern(param, BIND_VAR, allowDuplicates ? null : nameHash);\n }\n};\n\n// Parses a comma-separated list of expressions, and returns them as\n// an array. `close` is the token type that ends the list, and\n// `allowEmpty` can be turned on to allow subsequent commas with\n// nothing in between them to be parsed as `null` (which is needed\n// for array literals).\n\npp$5.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {\n var elts = [], first = true;\n while (!this.eat(close)) {\n if (!first) {\n this.expect(types$1.comma);\n if (allowTrailingComma && this.afterTrailingComma(close)) { break }\n } else { first = false; }\n\n var elt = (void 0);\n if (allowEmpty && this.type === types$1.comma)\n { elt = null; }\n else if (this.type === types$1.ellipsis) {\n elt = this.parseSpread(refDestructuringErrors);\n if (refDestructuringErrors && this.type === types$1.comma && refDestructuringErrors.trailingComma < 0)\n { refDestructuringErrors.trailingComma = this.start; }\n } else {\n elt = this.parseMaybeAssign(false, refDestructuringErrors);\n }\n elts.push(elt);\n }\n return elts\n};\n\npp$5.checkUnreserved = function(ref) {\n var start = ref.start;\n var end = ref.end;\n var name = ref.name;\n\n if (this.inGenerator && name === \"yield\")\n { this.raiseRecoverable(start, \"Cannot use 'yield' as identifier inside a generator\"); }\n if (this.inAsync && name === \"await\")\n { this.raiseRecoverable(start, \"Cannot use 'await' as identifier inside an async function\"); }\n if (this.currentThisScope().inClassFieldInit && name === \"arguments\")\n { this.raiseRecoverable(start, \"Cannot use 'arguments' in class field initializer\"); }\n if (this.inClassStaticBlock && (name === \"arguments\" || name === \"await\"))\n { this.raise(start, (\"Cannot use \" + name + \" in class static initialization block\")); }\n if (this.keywords.test(name))\n { this.raise(start, (\"Unexpected keyword '\" + name + \"'\")); }\n if (this.options.ecmaVersion < 6 &&\n this.input.slice(start, end).indexOf(\"\\\\\") !== -1) { return }\n var re = this.strict ? this.reservedWordsStrict : this.reservedWords;\n if (re.test(name)) {\n if (!this.inAsync && name === \"await\")\n { this.raiseRecoverable(start, \"Cannot use keyword 'await' outside an async function\"); }\n this.raiseRecoverable(start, (\"The keyword '\" + name + \"' is reserved\"));\n }\n};\n\n// Parse the next token as an identifier. If `liberal` is true (used\n// when parsing properties), it will also convert keywords into\n// identifiers.\n\npp$5.parseIdent = function(liberal) {\n var node = this.startNode();\n if (this.type === types$1.name) {\n node.name = this.value;\n } else if (this.type.keyword) {\n node.name = this.type.keyword;\n\n // To fix https://github.com/acornjs/acorn/issues/575\n // `class` and `function` keywords push new context into this.context.\n // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.\n // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword\n if ((node.name === \"class\" || node.name === \"function\") &&\n (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {\n this.context.pop();\n }\n } else {\n this.unexpected();\n }\n this.next(!!liberal);\n this.finishNode(node, \"Identifier\");\n if (!liberal) {\n this.checkUnreserved(node);\n if (node.name === \"await\" && !this.awaitIdentPos)\n { this.awaitIdentPos = node.start; }\n }\n return node\n};\n\npp$5.parsePrivateIdent = function() {\n var node = this.startNode();\n if (this.type === types$1.privateId) {\n node.name = this.value;\n } else {\n this.unexpected();\n }\n this.next();\n this.finishNode(node, \"PrivateIdentifier\");\n\n // For validating existence\n if (this.privateNameStack.length === 0) {\n this.raise(node.start, (\"Private field '#\" + (node.name) + \"' must be declared in an enclosing class\"));\n } else {\n this.privateNameStack[this.privateNameStack.length - 1].used.push(node);\n }\n\n return node\n};\n\n// Parses yield expression inside generator.\n\npp$5.parseYield = function(forInit) {\n if (!this.yieldPos) { this.yieldPos = this.start; }\n\n var node = this.startNode();\n this.next();\n if (this.type === types$1.semi || this.canInsertSemicolon() || (this.type !== types$1.star && !this.type.startsExpr)) {\n node.delegate = false;\n node.argument = null;\n } else {\n node.delegate = this.eat(types$1.star);\n node.argument = this.parseMaybeAssign(forInit);\n }\n return this.finishNode(node, \"YieldExpression\")\n};\n\npp$5.parseAwait = function(forInit) {\n if (!this.awaitPos) { this.awaitPos = this.start; }\n\n var node = this.startNode();\n this.next();\n node.argument = this.parseMaybeUnary(null, true, false, forInit);\n return this.finishNode(node, \"AwaitExpression\")\n};\n\nvar pp$4 = Parser.prototype;\n\n// This function is used to raise exceptions on parse errors. It\n// takes an offset integer (into the current `input`) to indicate\n// the location of the error, attaches the position to the end\n// of the error message, and then raises a `SyntaxError` with that\n// message.\n\npp$4.raise = function(pos, message) {\n var loc = getLineInfo(this.input, pos);\n message += \" (\" + loc.line + \":\" + loc.column + \")\";\n var err = new SyntaxError(message);\n err.pos = pos; err.loc = loc; err.raisedAt = this.pos;\n throw err\n};\n\npp$4.raiseRecoverable = pp$4.raise;\n\npp$4.curPosition = function() {\n if (this.options.locations) {\n return new Position(this.curLine, this.pos - this.lineStart)\n }\n};\n\nvar pp$3 = Parser.prototype;\n\nvar Scope = function Scope(flags) {\n this.flags = flags;\n // A list of var-declared names in the current lexical scope\n this.var = [];\n // A list of lexically-declared names in the current lexical scope\n this.lexical = [];\n // A list of lexically-declared FunctionDeclaration names in the current lexical scope\n this.functions = [];\n // A switch to disallow the identifier reference 'arguments'\n this.inClassFieldInit = false;\n};\n\n// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.\n\npp$3.enterScope = function(flags) {\n this.scopeStack.push(new Scope(flags));\n};\n\npp$3.exitScope = function() {\n this.scopeStack.pop();\n};\n\n// The spec says:\n// > At the top level of a function, or script, function declarations are\n// > treated like var declarations rather than like lexical declarations.\npp$3.treatFunctionsAsVarInScope = function(scope) {\n return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP)\n};\n\npp$3.declareName = function(name, bindingType, pos) {\n var redeclared = false;\n if (bindingType === BIND_LEXICAL) {\n var scope = this.currentScope();\n redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1;\n scope.lexical.push(name);\n if (this.inModule && (scope.flags & SCOPE_TOP))\n { delete this.undefinedExports[name]; }\n } else if (bindingType === BIND_SIMPLE_CATCH) {\n var scope$1 = this.currentScope();\n scope$1.lexical.push(name);\n } else if (bindingType === BIND_FUNCTION) {\n var scope$2 = this.currentScope();\n if (this.treatFunctionsAsVar)\n { redeclared = scope$2.lexical.indexOf(name) > -1; }\n else\n { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; }\n scope$2.functions.push(name);\n } else {\n for (var i = this.scopeStack.length - 1; i >= 0; --i) {\n var scope$3 = this.scopeStack[i];\n if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) ||\n !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) {\n redeclared = true;\n break\n }\n scope$3.var.push(name);\n if (this.inModule && (scope$3.flags & SCOPE_TOP))\n { delete this.undefinedExports[name]; }\n if (scope$3.flags & SCOPE_VAR) { break }\n }\n }\n if (redeclared) { this.raiseRecoverable(pos, (\"Identifier '\" + name + \"' has already been declared\")); }\n};\n\npp$3.checkLocalExport = function(id) {\n // scope.functions must be empty as Module code is always strict.\n if (this.scopeStack[0].lexical.indexOf(id.name) === -1 &&\n this.scopeStack[0].var.indexOf(id.name) === -1) {\n this.undefinedExports[id.name] = id;\n }\n};\n\npp$3.currentScope = function() {\n return this.scopeStack[this.scopeStack.length - 1]\n};\n\npp$3.currentVarScope = function() {\n for (var i = this.scopeStack.length - 1;; i--) {\n var scope = this.scopeStack[i];\n if (scope.flags & SCOPE_VAR) { return scope }\n }\n};\n\n// Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`.\npp$3.currentThisScope = function() {\n for (var i = this.scopeStack.length - 1;; i--) {\n var scope = this.scopeStack[i];\n if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope }\n }\n};\n\nvar Node = function Node(parser, pos, loc) {\n this.type = \"\";\n this.start = pos;\n this.end = 0;\n if (parser.options.locations)\n { this.loc = new SourceLocation(parser, loc); }\n if (parser.options.directSourceFile)\n { this.sourceFile = parser.options.directSourceFile; }\n if (parser.options.ranges)\n { this.range = [pos, 0]; }\n};\n\n// Start an AST node, attaching a start offset.\n\nvar pp$2 = Parser.prototype;\n\npp$2.startNode = function() {\n return new Node(this, this.start, this.startLoc)\n};\n\npp$2.startNodeAt = function(pos, loc) {\n return new Node(this, pos, loc)\n};\n\n// Finish an AST node, adding `type` and `end` properties.\n\nfunction finishNodeAt(node, type, pos, loc) {\n node.type = type;\n node.end = pos;\n if (this.options.locations)\n { node.loc.end = loc; }\n if (this.options.ranges)\n { node.range[1] = pos; }\n return node\n}\n\npp$2.finishNode = function(node, type) {\n return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)\n};\n\n// Finish node at given position\n\npp$2.finishNodeAt = function(node, type, pos, loc) {\n return finishNodeAt.call(this, node, type, pos, loc)\n};\n\npp$2.copyNode = function(node) {\n var newNode = new Node(this, node.start, this.startLoc);\n for (var prop in node) { newNode[prop] = node[prop]; }\n return newNode\n};\n\n// This file contains Unicode properties extracted from the ECMAScript specification.\n// The lists are extracted like so:\n// $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText)\n\n// #table-binary-unicode-properties\nvar ecma9BinaryProperties = \"ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS\";\nvar ecma10BinaryProperties = ecma9BinaryProperties + \" Extended_Pictographic\";\nvar ecma11BinaryProperties = ecma10BinaryProperties;\nvar ecma12BinaryProperties = ecma11BinaryProperties + \" EBase EComp EMod EPres ExtPict\";\nvar ecma13BinaryProperties = ecma12BinaryProperties;\nvar ecma14BinaryProperties = ecma13BinaryProperties;\n\nvar unicodeBinaryProperties = {\n 9: ecma9BinaryProperties,\n 10: ecma10BinaryProperties,\n 11: ecma11BinaryProperties,\n 12: ecma12BinaryProperties,\n 13: ecma13BinaryProperties,\n 14: ecma14BinaryProperties\n};\n\n// #table-unicode-general-category-values\nvar unicodeGeneralCategoryValues = \"Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu\";\n\n// #table-unicode-script-values\nvar ecma9ScriptValues = \"Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb\";\nvar ecma10ScriptValues = ecma9ScriptValues + \" Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd\";\nvar ecma11ScriptValues = ecma10ScriptValues + \" Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho\";\nvar ecma12ScriptValues = ecma11ScriptValues + \" Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi\";\nvar ecma13ScriptValues = ecma12ScriptValues + \" Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith\";\nvar ecma14ScriptValues = ecma13ScriptValues + \" Kawi Nag_Mundari Nagm\";\n\nvar unicodeScriptValues = {\n 9: ecma9ScriptValues,\n 10: ecma10ScriptValues,\n 11: ecma11ScriptValues,\n 12: ecma12ScriptValues,\n 13: ecma13ScriptValues,\n 14: ecma14ScriptValues\n};\n\nvar data = {};\nfunction buildUnicodeData(ecmaVersion) {\n var d = data[ecmaVersion] = {\n binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + \" \" + unicodeGeneralCategoryValues),\n nonBinary: {\n General_Category: wordsRegexp(unicodeGeneralCategoryValues),\n Script: wordsRegexp(unicodeScriptValues[ecmaVersion])\n }\n };\n d.nonBinary.Script_Extensions = d.nonBinary.Script;\n\n d.nonBinary.gc = d.nonBinary.General_Category;\n d.nonBinary.sc = d.nonBinary.Script;\n d.nonBinary.scx = d.nonBinary.Script_Extensions;\n}\n\nfor (var i = 0, list = [9, 10, 11, 12, 13, 14]; i < list.length; i += 1) {\n var ecmaVersion = list[i];\n\n buildUnicodeData(ecmaVersion);\n}\n\nvar pp$1 = Parser.prototype;\n\nvar RegExpValidationState = function RegExpValidationState(parser) {\n this.parser = parser;\n this.validFlags = \"gim\" + (parser.options.ecmaVersion >= 6 ? \"uy\" : \"\") + (parser.options.ecmaVersion >= 9 ? \"s\" : \"\") + (parser.options.ecmaVersion >= 13 ? \"d\" : \"\");\n this.unicodeProperties = data[parser.options.ecmaVersion >= 14 ? 14 : parser.options.ecmaVersion];\n this.source = \"\";\n this.flags = \"\";\n this.start = 0;\n this.switchU = false;\n this.switchN = false;\n this.pos = 0;\n this.lastIntValue = 0;\n this.lastStringValue = \"\";\n this.lastAssertionIsQuantifiable = false;\n this.numCapturingParens = 0;\n this.maxBackReference = 0;\n this.groupNames = [];\n this.backReferenceNames = [];\n};\n\nRegExpValidationState.prototype.reset = function reset (start, pattern, flags) {\n var unicode = flags.indexOf(\"u\") !== -1;\n this.start = start | 0;\n this.source = pattern + \"\";\n this.flags = flags;\n this.switchU = unicode && this.parser.options.ecmaVersion >= 6;\n this.switchN = unicode && this.parser.options.ecmaVersion >= 9;\n};\n\nRegExpValidationState.prototype.raise = function raise (message) {\n this.parser.raiseRecoverable(this.start, (\"Invalid regular expression: /\" + (this.source) + \"/: \" + message));\n};\n\n// If u flag is given, this returns the code point at the index (it combines a surrogate pair).\n// Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).\nRegExpValidationState.prototype.at = function at (i, forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n var s = this.source;\n var l = s.length;\n if (i >= l) {\n return -1\n }\n var c = s.charCodeAt(i);\n if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {\n return c\n }\n var next = s.charCodeAt(i + 1);\n return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c\n};\n\nRegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n var s = this.source;\n var l = s.length;\n if (i >= l) {\n return l\n }\n var c = s.charCodeAt(i), next;\n if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l ||\n (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) {\n return i + 1\n }\n return i + 2\n};\n\nRegExpValidationState.prototype.current = function current (forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n return this.at(this.pos, forceU)\n};\n\nRegExpValidationState.prototype.lookahead = function lookahead (forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n return this.at(this.nextIndex(this.pos, forceU), forceU)\n};\n\nRegExpValidationState.prototype.advance = function advance (forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n this.pos = this.nextIndex(this.pos, forceU);\n};\n\nRegExpValidationState.prototype.eat = function eat (ch, forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n if (this.current(forceU) === ch) {\n this.advance(forceU);\n return true\n }\n return false\n};\n\n/**\n * Validate the flags part of a given RegExpLiteral.\n *\n * @param {RegExpValidationState} state The state to validate RegExp.\n * @returns {void}\n */\npp$1.validateRegExpFlags = function(state) {\n var validFlags = state.validFlags;\n var flags = state.flags;\n\n for (var i = 0; i < flags.length; i++) {\n var flag = flags.charAt(i);\n if (validFlags.indexOf(flag) === -1) {\n this.raise(state.start, \"Invalid regular expression flag\");\n }\n if (flags.indexOf(flag, i + 1) > -1) {\n this.raise(state.start, \"Duplicate regular expression flag\");\n }\n }\n};\n\n/**\n * Validate the pattern part of a given RegExpLiteral.\n *\n * @param {RegExpValidationState} state The state to validate RegExp.\n * @returns {void}\n */\npp$1.validateRegExpPattern = function(state) {\n this.regexp_pattern(state);\n\n // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of\n // parsing contains a |GroupName|, reparse with the goal symbol\n // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*\n // exception if _P_ did not conform to the grammar, if any elements of _P_\n // were not matched by the parse, or if any Early Error conditions exist.\n if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) {\n state.switchN = true;\n this.regexp_pattern(state);\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern\npp$1.regexp_pattern = function(state) {\n state.pos = 0;\n state.lastIntValue = 0;\n state.lastStringValue = \"\";\n state.lastAssertionIsQuantifiable = false;\n state.numCapturingParens = 0;\n state.maxBackReference = 0;\n state.groupNames.length = 0;\n state.backReferenceNames.length = 0;\n\n this.regexp_disjunction(state);\n\n if (state.pos !== state.source.length) {\n // Make the same messages as V8.\n if (state.eat(0x29 /* ) */)) {\n state.raise(\"Unmatched ')'\");\n }\n if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) {\n state.raise(\"Lone quantifier brackets\");\n }\n }\n if (state.maxBackReference > state.numCapturingParens) {\n state.raise(\"Invalid escape\");\n }\n for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {\n var name = list[i];\n\n if (state.groupNames.indexOf(name) === -1) {\n state.raise(\"Invalid named capture referenced\");\n }\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction\npp$1.regexp_disjunction = function(state) {\n this.regexp_alternative(state);\n while (state.eat(0x7C /* | */)) {\n this.regexp_alternative(state);\n }\n\n // Make the same message as V8.\n if (this.regexp_eatQuantifier(state, true)) {\n state.raise(\"Nothing to repeat\");\n }\n if (state.eat(0x7B /* { */)) {\n state.raise(\"Lone quantifier brackets\");\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative\npp$1.regexp_alternative = function(state) {\n while (state.pos < state.source.length && this.regexp_eatTerm(state))\n { }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term\npp$1.regexp_eatTerm = function(state) {\n if (this.regexp_eatAssertion(state)) {\n // Handle `QuantifiableAssertion Quantifier` alternative.\n // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion\n // is a QuantifiableAssertion.\n if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {\n // Make the same message as V8.\n if (state.switchU) {\n state.raise(\"Invalid quantifier\");\n }\n }\n return true\n }\n\n if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {\n this.regexp_eatQuantifier(state);\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion\npp$1.regexp_eatAssertion = function(state) {\n var start = state.pos;\n state.lastAssertionIsQuantifiable = false;\n\n // ^, $\n if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {\n return true\n }\n\n // \\b \\B\n if (state.eat(0x5C /* \\ */)) {\n if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {\n return true\n }\n state.pos = start;\n }\n\n // Lookahead / Lookbehind\n if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {\n var lookbehind = false;\n if (this.options.ecmaVersion >= 9) {\n lookbehind = state.eat(0x3C /* < */);\n }\n if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {\n this.regexp_disjunction(state);\n if (!state.eat(0x29 /* ) */)) {\n state.raise(\"Unterminated group\");\n }\n state.lastAssertionIsQuantifiable = !lookbehind;\n return true\n }\n }\n\n state.pos = start;\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier\npp$1.regexp_eatQuantifier = function(state, noError) {\n if ( noError === void 0 ) noError = false;\n\n if (this.regexp_eatQuantifierPrefix(state, noError)) {\n state.eat(0x3F /* ? */);\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix\npp$1.regexp_eatQuantifierPrefix = function(state, noError) {\n return (\n state.eat(0x2A /* * */) ||\n state.eat(0x2B /* + */) ||\n state.eat(0x3F /* ? */) ||\n this.regexp_eatBracedQuantifier(state, noError)\n )\n};\npp$1.regexp_eatBracedQuantifier = function(state, noError) {\n var start = state.pos;\n if (state.eat(0x7B /* { */)) {\n var min = 0, max = -1;\n if (this.regexp_eatDecimalDigits(state)) {\n min = state.lastIntValue;\n if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {\n max = state.lastIntValue;\n }\n if (state.eat(0x7D /* } */)) {\n // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term\n if (max !== -1 && max < min && !noError) {\n state.raise(\"numbers out of order in {} quantifier\");\n }\n return true\n }\n }\n if (state.switchU && !noError) {\n state.raise(\"Incomplete quantifier\");\n }\n state.pos = start;\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Atom\npp$1.regexp_eatAtom = function(state) {\n return (\n this.regexp_eatPatternCharacters(state) ||\n state.eat(0x2E /* . */) ||\n this.regexp_eatReverseSolidusAtomEscape(state) ||\n this.regexp_eatCharacterClass(state) ||\n this.regexp_eatUncapturingGroup(state) ||\n this.regexp_eatCapturingGroup(state)\n )\n};\npp$1.regexp_eatReverseSolidusAtomEscape = function(state) {\n var start = state.pos;\n if (state.eat(0x5C /* \\ */)) {\n if (this.regexp_eatAtomEscape(state)) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$1.regexp_eatUncapturingGroup = function(state) {\n var start = state.pos;\n if (state.eat(0x28 /* ( */)) {\n if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) {\n this.regexp_disjunction(state);\n if (state.eat(0x29 /* ) */)) {\n return true\n }\n state.raise(\"Unterminated group\");\n }\n state.pos = start;\n }\n return false\n};\npp$1.regexp_eatCapturingGroup = function(state) {\n if (state.eat(0x28 /* ( */)) {\n if (this.options.ecmaVersion >= 9) {\n this.regexp_groupSpecifier(state);\n } else if (state.current() === 0x3F /* ? */) {\n state.raise(\"Invalid group\");\n }\n this.regexp_disjunction(state);\n if (state.eat(0x29 /* ) */)) {\n state.numCapturingParens += 1;\n return true\n }\n state.raise(\"Unterminated group\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom\npp$1.regexp_eatExtendedAtom = function(state) {\n return (\n state.eat(0x2E /* . */) ||\n this.regexp_eatReverseSolidusAtomEscape(state) ||\n this.regexp_eatCharacterClass(state) ||\n this.regexp_eatUncapturingGroup(state) ||\n this.regexp_eatCapturingGroup(state) ||\n this.regexp_eatInvalidBracedQuantifier(state) ||\n this.regexp_eatExtendedPatternCharacter(state)\n )\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier\npp$1.regexp_eatInvalidBracedQuantifier = function(state) {\n if (this.regexp_eatBracedQuantifier(state, true)) {\n state.raise(\"Nothing to repeat\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter\npp$1.regexp_eatSyntaxCharacter = function(state) {\n var ch = state.current();\n if (isSyntaxCharacter(ch)) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n return false\n};\nfunction isSyntaxCharacter(ch) {\n return (\n ch === 0x24 /* $ */ ||\n ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||\n ch === 0x2E /* . */ ||\n ch === 0x3F /* ? */ ||\n ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||\n ch >= 0x7B /* { */ && ch <= 0x7D /* } */\n )\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter\n// But eat eager.\npp$1.regexp_eatPatternCharacters = function(state) {\n var start = state.pos;\n var ch = 0;\n while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {\n state.advance();\n }\n return state.pos !== start\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter\npp$1.regexp_eatExtendedPatternCharacter = function(state) {\n var ch = state.current();\n if (\n ch !== -1 &&\n ch !== 0x24 /* $ */ &&\n !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&\n ch !== 0x2E /* . */ &&\n ch !== 0x3F /* ? */ &&\n ch !== 0x5B /* [ */ &&\n ch !== 0x5E /* ^ */ &&\n ch !== 0x7C /* | */\n ) {\n state.advance();\n return true\n }\n return false\n};\n\n// GroupSpecifier ::\n// [empty]\n// `?` GroupName\npp$1.regexp_groupSpecifier = function(state) {\n if (state.eat(0x3F /* ? */)) {\n if (this.regexp_eatGroupName(state)) {\n if (state.groupNames.indexOf(state.lastStringValue) !== -1) {\n state.raise(\"Duplicate capture group name\");\n }\n state.groupNames.push(state.lastStringValue);\n return\n }\n state.raise(\"Invalid group\");\n }\n};\n\n// GroupName ::\n// `<` RegExpIdentifierName `>`\n// Note: this updates `state.lastStringValue` property with the eaten name.\npp$1.regexp_eatGroupName = function(state) {\n state.lastStringValue = \"\";\n if (state.eat(0x3C /* < */)) {\n if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {\n return true\n }\n state.raise(\"Invalid capture group name\");\n }\n return false\n};\n\n// RegExpIdentifierName ::\n// RegExpIdentifierStart\n// RegExpIdentifierName RegExpIdentifierPart\n// Note: this updates `state.lastStringValue` property with the eaten name.\npp$1.regexp_eatRegExpIdentifierName = function(state) {\n state.lastStringValue = \"\";\n if (this.regexp_eatRegExpIdentifierStart(state)) {\n state.lastStringValue += codePointToString(state.lastIntValue);\n while (this.regexp_eatRegExpIdentifierPart(state)) {\n state.lastStringValue += codePointToString(state.lastIntValue);\n }\n return true\n }\n return false\n};\n\n// RegExpIdentifierStart ::\n// UnicodeIDStart\n// `$`\n// `_`\n// `\\` RegExpUnicodeEscapeSequence[+U]\npp$1.regexp_eatRegExpIdentifierStart = function(state) {\n var start = state.pos;\n var forceU = this.options.ecmaVersion >= 11;\n var ch = state.current(forceU);\n state.advance(forceU);\n\n if (ch === 0x5C /* \\ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {\n ch = state.lastIntValue;\n }\n if (isRegExpIdentifierStart(ch)) {\n state.lastIntValue = ch;\n return true\n }\n\n state.pos = start;\n return false\n};\nfunction isRegExpIdentifierStart(ch) {\n return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */\n}\n\n// RegExpIdentifierPart ::\n// UnicodeIDContinue\n// `$`\n// `_`\n// `\\` RegExpUnicodeEscapeSequence[+U]\n// \n// \npp$1.regexp_eatRegExpIdentifierPart = function(state) {\n var start = state.pos;\n var forceU = this.options.ecmaVersion >= 11;\n var ch = state.current(forceU);\n state.advance(forceU);\n\n if (ch === 0x5C /* \\ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {\n ch = state.lastIntValue;\n }\n if (isRegExpIdentifierPart(ch)) {\n state.lastIntValue = ch;\n return true\n }\n\n state.pos = start;\n return false\n};\nfunction isRegExpIdentifierPart(ch) {\n return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* */ || ch === 0x200D /* */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape\npp$1.regexp_eatAtomEscape = function(state) {\n if (\n this.regexp_eatBackReference(state) ||\n this.regexp_eatCharacterClassEscape(state) ||\n this.regexp_eatCharacterEscape(state) ||\n (state.switchN && this.regexp_eatKGroupName(state))\n ) {\n return true\n }\n if (state.switchU) {\n // Make the same message as V8.\n if (state.current() === 0x63 /* c */) {\n state.raise(\"Invalid unicode escape\");\n }\n state.raise(\"Invalid escape\");\n }\n return false\n};\npp$1.regexp_eatBackReference = function(state) {\n var start = state.pos;\n if (this.regexp_eatDecimalEscape(state)) {\n var n = state.lastIntValue;\n if (state.switchU) {\n // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape\n if (n > state.maxBackReference) {\n state.maxBackReference = n;\n }\n return true\n }\n if (n <= state.numCapturingParens) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$1.regexp_eatKGroupName = function(state) {\n if (state.eat(0x6B /* k */)) {\n if (this.regexp_eatGroupName(state)) {\n state.backReferenceNames.push(state.lastStringValue);\n return true\n }\n state.raise(\"Invalid named reference\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape\npp$1.regexp_eatCharacterEscape = function(state) {\n return (\n this.regexp_eatControlEscape(state) ||\n this.regexp_eatCControlLetter(state) ||\n this.regexp_eatZero(state) ||\n this.regexp_eatHexEscapeSequence(state) ||\n this.regexp_eatRegExpUnicodeEscapeSequence(state, false) ||\n (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||\n this.regexp_eatIdentityEscape(state)\n )\n};\npp$1.regexp_eatCControlLetter = function(state) {\n var start = state.pos;\n if (state.eat(0x63 /* c */)) {\n if (this.regexp_eatControlLetter(state)) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$1.regexp_eatZero = function(state) {\n if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {\n state.lastIntValue = 0;\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape\npp$1.regexp_eatControlEscape = function(state) {\n var ch = state.current();\n if (ch === 0x74 /* t */) {\n state.lastIntValue = 0x09; /* \\t */\n state.advance();\n return true\n }\n if (ch === 0x6E /* n */) {\n state.lastIntValue = 0x0A; /* \\n */\n state.advance();\n return true\n }\n if (ch === 0x76 /* v */) {\n state.lastIntValue = 0x0B; /* \\v */\n state.advance();\n return true\n }\n if (ch === 0x66 /* f */) {\n state.lastIntValue = 0x0C; /* \\f */\n state.advance();\n return true\n }\n if (ch === 0x72 /* r */) {\n state.lastIntValue = 0x0D; /* \\r */\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter\npp$1.regexp_eatControlLetter = function(state) {\n var ch = state.current();\n if (isControlLetter(ch)) {\n state.lastIntValue = ch % 0x20;\n state.advance();\n return true\n }\n return false\n};\nfunction isControlLetter(ch) {\n return (\n (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||\n (ch >= 0x61 /* a */ && ch <= 0x7A /* z */)\n )\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence\npp$1.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) {\n if ( forceU === void 0 ) forceU = false;\n\n var start = state.pos;\n var switchU = forceU || state.switchU;\n\n if (state.eat(0x75 /* u */)) {\n if (this.regexp_eatFixedHexDigits(state, 4)) {\n var lead = state.lastIntValue;\n if (switchU && lead >= 0xD800 && lead <= 0xDBFF) {\n var leadSurrogateEnd = state.pos;\n if (state.eat(0x5C /* \\ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {\n var trail = state.lastIntValue;\n if (trail >= 0xDC00 && trail <= 0xDFFF) {\n state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n return true\n }\n }\n state.pos = leadSurrogateEnd;\n state.lastIntValue = lead;\n }\n return true\n }\n if (\n switchU &&\n state.eat(0x7B /* { */) &&\n this.regexp_eatHexDigits(state) &&\n state.eat(0x7D /* } */) &&\n isValidUnicode(state.lastIntValue)\n ) {\n return true\n }\n if (switchU) {\n state.raise(\"Invalid unicode escape\");\n }\n state.pos = start;\n }\n\n return false\n};\nfunction isValidUnicode(ch) {\n return ch >= 0 && ch <= 0x10FFFF\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape\npp$1.regexp_eatIdentityEscape = function(state) {\n if (state.switchU) {\n if (this.regexp_eatSyntaxCharacter(state)) {\n return true\n }\n if (state.eat(0x2F /* / */)) {\n state.lastIntValue = 0x2F; /* / */\n return true\n }\n return false\n }\n\n var ch = state.current();\n if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape\npp$1.regexp_eatDecimalEscape = function(state) {\n state.lastIntValue = 0;\n var ch = state.current();\n if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {\n do {\n state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);\n state.advance();\n } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape\npp$1.regexp_eatCharacterClassEscape = function(state) {\n var ch = state.current();\n\n if (isCharacterClassEscape(ch)) {\n state.lastIntValue = -1;\n state.advance();\n return true\n }\n\n if (\n state.switchU &&\n this.options.ecmaVersion >= 9 &&\n (ch === 0x50 /* P */ || ch === 0x70 /* p */)\n ) {\n state.lastIntValue = -1;\n state.advance();\n if (\n state.eat(0x7B /* { */) &&\n this.regexp_eatUnicodePropertyValueExpression(state) &&\n state.eat(0x7D /* } */)\n ) {\n return true\n }\n state.raise(\"Invalid property name\");\n }\n\n return false\n};\nfunction isCharacterClassEscape(ch) {\n return (\n ch === 0x64 /* d */ ||\n ch === 0x44 /* D */ ||\n ch === 0x73 /* s */ ||\n ch === 0x53 /* S */ ||\n ch === 0x77 /* w */ ||\n ch === 0x57 /* W */\n )\n}\n\n// UnicodePropertyValueExpression ::\n// UnicodePropertyName `=` UnicodePropertyValue\n// LoneUnicodePropertyNameOrValue\npp$1.regexp_eatUnicodePropertyValueExpression = function(state) {\n var start = state.pos;\n\n // UnicodePropertyName `=` UnicodePropertyValue\n if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {\n var name = state.lastStringValue;\n if (this.regexp_eatUnicodePropertyValue(state)) {\n var value = state.lastStringValue;\n this.regexp_validateUnicodePropertyNameAndValue(state, name, value);\n return true\n }\n }\n state.pos = start;\n\n // LoneUnicodePropertyNameOrValue\n if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {\n var nameOrValue = state.lastStringValue;\n this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue);\n return true\n }\n return false\n};\npp$1.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {\n if (!hasOwn(state.unicodeProperties.nonBinary, name))\n { state.raise(\"Invalid property name\"); }\n if (!state.unicodeProperties.nonBinary[name].test(value))\n { state.raise(\"Invalid property value\"); }\n};\npp$1.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {\n if (!state.unicodeProperties.binary.test(nameOrValue))\n { state.raise(\"Invalid property name\"); }\n};\n\n// UnicodePropertyName ::\n// UnicodePropertyNameCharacters\npp$1.regexp_eatUnicodePropertyName = function(state) {\n var ch = 0;\n state.lastStringValue = \"\";\n while (isUnicodePropertyNameCharacter(ch = state.current())) {\n state.lastStringValue += codePointToString(ch);\n state.advance();\n }\n return state.lastStringValue !== \"\"\n};\nfunction isUnicodePropertyNameCharacter(ch) {\n return isControlLetter(ch) || ch === 0x5F /* _ */\n}\n\n// UnicodePropertyValue ::\n// UnicodePropertyValueCharacters\npp$1.regexp_eatUnicodePropertyValue = function(state) {\n var ch = 0;\n state.lastStringValue = \"\";\n while (isUnicodePropertyValueCharacter(ch = state.current())) {\n state.lastStringValue += codePointToString(ch);\n state.advance();\n }\n return state.lastStringValue !== \"\"\n};\nfunction isUnicodePropertyValueCharacter(ch) {\n return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)\n}\n\n// LoneUnicodePropertyNameOrValue ::\n// UnicodePropertyValueCharacters\npp$1.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {\n return this.regexp_eatUnicodePropertyValue(state)\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass\npp$1.regexp_eatCharacterClass = function(state) {\n if (state.eat(0x5B /* [ */)) {\n state.eat(0x5E /* ^ */);\n this.regexp_classRanges(state);\n if (state.eat(0x5D /* ] */)) {\n return true\n }\n // Unreachable since it threw \"unterminated regular expression\" error before.\n state.raise(\"Unterminated character class\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges\n// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges\n// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash\npp$1.regexp_classRanges = function(state) {\n while (this.regexp_eatClassAtom(state)) {\n var left = state.lastIntValue;\n if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) {\n var right = state.lastIntValue;\n if (state.switchU && (left === -1 || right === -1)) {\n state.raise(\"Invalid character class\");\n }\n if (left !== -1 && right !== -1 && left > right) {\n state.raise(\"Range out of order in character class\");\n }\n }\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash\npp$1.regexp_eatClassAtom = function(state) {\n var start = state.pos;\n\n if (state.eat(0x5C /* \\ */)) {\n if (this.regexp_eatClassEscape(state)) {\n return true\n }\n if (state.switchU) {\n // Make the same message as V8.\n var ch$1 = state.current();\n if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {\n state.raise(\"Invalid class escape\");\n }\n state.raise(\"Invalid escape\");\n }\n state.pos = start;\n }\n\n var ch = state.current();\n if (ch !== 0x5D /* ] */) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape\npp$1.regexp_eatClassEscape = function(state) {\n var start = state.pos;\n\n if (state.eat(0x62 /* b */)) {\n state.lastIntValue = 0x08; /* */\n return true\n }\n\n if (state.switchU && state.eat(0x2D /* - */)) {\n state.lastIntValue = 0x2D; /* - */\n return true\n }\n\n if (!state.switchU && state.eat(0x63 /* c */)) {\n if (this.regexp_eatClassControlLetter(state)) {\n return true\n }\n state.pos = start;\n }\n\n return (\n this.regexp_eatCharacterClassEscape(state) ||\n this.regexp_eatCharacterEscape(state)\n )\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter\npp$1.regexp_eatClassControlLetter = function(state) {\n var ch = state.current();\n if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {\n state.lastIntValue = ch % 0x20;\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence\npp$1.regexp_eatHexEscapeSequence = function(state) {\n var start = state.pos;\n if (state.eat(0x78 /* x */)) {\n if (this.regexp_eatFixedHexDigits(state, 2)) {\n return true\n }\n if (state.switchU) {\n state.raise(\"Invalid escape\");\n }\n state.pos = start;\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits\npp$1.regexp_eatDecimalDigits = function(state) {\n var start = state.pos;\n var ch = 0;\n state.lastIntValue = 0;\n while (isDecimalDigit(ch = state.current())) {\n state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);\n state.advance();\n }\n return state.pos !== start\n};\nfunction isDecimalDigit(ch) {\n return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits\npp$1.regexp_eatHexDigits = function(state) {\n var start = state.pos;\n var ch = 0;\n state.lastIntValue = 0;\n while (isHexDigit(ch = state.current())) {\n state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);\n state.advance();\n }\n return state.pos !== start\n};\nfunction isHexDigit(ch) {\n return (\n (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||\n (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||\n (ch >= 0x61 /* a */ && ch <= 0x66 /* f */)\n )\n}\nfunction hexToInt(ch) {\n if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {\n return 10 + (ch - 0x41 /* A */)\n }\n if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {\n return 10 + (ch - 0x61 /* a */)\n }\n return ch - 0x30 /* 0 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence\n// Allows only 0-377(octal) i.e. 0-255(decimal).\npp$1.regexp_eatLegacyOctalEscapeSequence = function(state) {\n if (this.regexp_eatOctalDigit(state)) {\n var n1 = state.lastIntValue;\n if (this.regexp_eatOctalDigit(state)) {\n var n2 = state.lastIntValue;\n if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {\n state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;\n } else {\n state.lastIntValue = n1 * 8 + n2;\n }\n } else {\n state.lastIntValue = n1;\n }\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit\npp$1.regexp_eatOctalDigit = function(state) {\n var ch = state.current();\n if (isOctalDigit(ch)) {\n state.lastIntValue = ch - 0x30; /* 0 */\n state.advance();\n return true\n }\n state.lastIntValue = 0;\n return false\n};\nfunction isOctalDigit(ch) {\n return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit\n// And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence\npp$1.regexp_eatFixedHexDigits = function(state, length) {\n var start = state.pos;\n state.lastIntValue = 0;\n for (var i = 0; i < length; ++i) {\n var ch = state.current();\n if (!isHexDigit(ch)) {\n state.pos = start;\n return false\n }\n state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);\n state.advance();\n }\n return true\n};\n\n// Object type used to represent tokens. Note that normally, tokens\n// simply exist as properties on the parser object. This is only\n// used for the onToken callback and the external tokenizer.\n\nvar Token = function Token(p) {\n this.type = p.type;\n this.value = p.value;\n this.start = p.start;\n this.end = p.end;\n if (p.options.locations)\n { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }\n if (p.options.ranges)\n { this.range = [p.start, p.end]; }\n};\n\n// ## Tokenizer\n\nvar pp = Parser.prototype;\n\n// Move to the next token\n\npp.next = function(ignoreEscapeSequenceInKeyword) {\n if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc)\n { this.raiseRecoverable(this.start, \"Escape sequence in keyword \" + this.type.keyword); }\n if (this.options.onToken)\n { this.options.onToken(new Token(this)); }\n\n this.lastTokEnd = this.end;\n this.lastTokStart = this.start;\n this.lastTokEndLoc = this.endLoc;\n this.lastTokStartLoc = this.startLoc;\n this.nextToken();\n};\n\npp.getToken = function() {\n this.next();\n return new Token(this)\n};\n\n// If we're in an ES6 environment, make parsers iterable\nif (typeof Symbol !== \"undefined\")\n { pp[Symbol.iterator] = function() {\n var this$1$1 = this;\n\n return {\n next: function () {\n var token = this$1$1.getToken();\n return {\n done: token.type === types$1.eof,\n value: token\n }\n }\n }\n }; }\n\n// Toggle strict mode. Re-reads the next number or string to please\n// pedantic tests (`\"use strict\"; 010;` should fail).\n\n// Read a single token, updating the parser object's token-related\n// properties.\n\npp.nextToken = function() {\n var curContext = this.curContext();\n if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }\n\n this.start = this.pos;\n if (this.options.locations) { this.startLoc = this.curPosition(); }\n if (this.pos >= this.input.length) { return this.finishToken(types$1.eof) }\n\n if (curContext.override) { return curContext.override(this) }\n else { this.readToken(this.fullCharCodeAtPos()); }\n};\n\npp.readToken = function(code) {\n // Identifier or keyword. '\\uXXXX' sequences are allowed in\n // identifiers, so '\\' also dispatches to that.\n if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\\' */)\n { return this.readWord() }\n\n return this.getTokenFromCode(code)\n};\n\npp.fullCharCodeAtPos = function() {\n var code = this.input.charCodeAt(this.pos);\n if (code <= 0xd7ff || code >= 0xdc00) { return code }\n var next = this.input.charCodeAt(this.pos + 1);\n return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00\n};\n\npp.skipBlockComment = function() {\n var startLoc = this.options.onComment && this.curPosition();\n var start = this.pos, end = this.input.indexOf(\"*/\", this.pos += 2);\n if (end === -1) { this.raise(this.pos - 2, \"Unterminated comment\"); }\n this.pos = end + 2;\n if (this.options.locations) {\n for (var nextBreak = (void 0), pos = start; (nextBreak = nextLineBreak(this.input, pos, this.pos)) > -1;) {\n ++this.curLine;\n pos = this.lineStart = nextBreak;\n }\n }\n if (this.options.onComment)\n { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,\n startLoc, this.curPosition()); }\n};\n\npp.skipLineComment = function(startSkip) {\n var start = this.pos;\n var startLoc = this.options.onComment && this.curPosition();\n var ch = this.input.charCodeAt(this.pos += startSkip);\n while (this.pos < this.input.length && !isNewLine(ch)) {\n ch = this.input.charCodeAt(++this.pos);\n }\n if (this.options.onComment)\n { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,\n startLoc, this.curPosition()); }\n};\n\n// Called at the start of the parse and after every token. Skips\n// whitespace and comments, and.\n\npp.skipSpace = function() {\n loop: while (this.pos < this.input.length) {\n var ch = this.input.charCodeAt(this.pos);\n switch (ch) {\n case 32: case 160: // ' '\n ++this.pos;\n break\n case 13:\n if (this.input.charCodeAt(this.pos + 1) === 10) {\n ++this.pos;\n }\n case 10: case 8232: case 8233:\n ++this.pos;\n if (this.options.locations) {\n ++this.curLine;\n this.lineStart = this.pos;\n }\n break\n case 47: // '/'\n switch (this.input.charCodeAt(this.pos + 1)) {\n case 42: // '*'\n this.skipBlockComment();\n break\n case 47:\n this.skipLineComment(2);\n break\n default:\n break loop\n }\n break\n default:\n if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {\n ++this.pos;\n } else {\n break loop\n }\n }\n }\n};\n\n// Called at the end of every token. Sets `end`, `val`, and\n// maintains `context` and `exprAllowed`, and skips the space after\n// the token, so that the next one's `start` will point at the\n// right position.\n\npp.finishToken = function(type, val) {\n this.end = this.pos;\n if (this.options.locations) { this.endLoc = this.curPosition(); }\n var prevType = this.type;\n this.type = type;\n this.value = val;\n\n this.updateContext(prevType);\n};\n\n// ### Token reading\n\n// This is the function that is called to fetch the next token. It\n// is somewhat obscure, because it works in character codes rather\n// than characters, and because operator parsing has been inlined\n// into it.\n//\n// All in the name of speed.\n//\npp.readToken_dot = function() {\n var next = this.input.charCodeAt(this.pos + 1);\n if (next >= 48 && next <= 57) { return this.readNumber(true) }\n var next2 = this.input.charCodeAt(this.pos + 2);\n if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'\n this.pos += 3;\n return this.finishToken(types$1.ellipsis)\n } else {\n ++this.pos;\n return this.finishToken(types$1.dot)\n }\n};\n\npp.readToken_slash = function() { // '/'\n var next = this.input.charCodeAt(this.pos + 1);\n if (this.exprAllowed) { ++this.pos; return this.readRegexp() }\n if (next === 61) { return this.finishOp(types$1.assign, 2) }\n return this.finishOp(types$1.slash, 1)\n};\n\npp.readToken_mult_modulo_exp = function(code) { // '%*'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n var tokentype = code === 42 ? types$1.star : types$1.modulo;\n\n // exponentiation operator ** and **=\n if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {\n ++size;\n tokentype = types$1.starstar;\n next = this.input.charCodeAt(this.pos + 2);\n }\n\n if (next === 61) { return this.finishOp(types$1.assign, size + 1) }\n return this.finishOp(tokentype, size)\n};\n\npp.readToken_pipe_amp = function(code) { // '|&'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === code) {\n if (this.options.ecmaVersion >= 12) {\n var next2 = this.input.charCodeAt(this.pos + 2);\n if (next2 === 61) { return this.finishOp(types$1.assign, 3) }\n }\n return this.finishOp(code === 124 ? types$1.logicalOR : types$1.logicalAND, 2)\n }\n if (next === 61) { return this.finishOp(types$1.assign, 2) }\n return this.finishOp(code === 124 ? types$1.bitwiseOR : types$1.bitwiseAND, 1)\n};\n\npp.readToken_caret = function() { // '^'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === 61) { return this.finishOp(types$1.assign, 2) }\n return this.finishOp(types$1.bitwiseXOR, 1)\n};\n\npp.readToken_plus_min = function(code) { // '+-'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === code) {\n if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 &&\n (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {\n // A `-->` line comment\n this.skipLineComment(3);\n this.skipSpace();\n return this.nextToken()\n }\n return this.finishOp(types$1.incDec, 2)\n }\n if (next === 61) { return this.finishOp(types$1.assign, 2) }\n return this.finishOp(types$1.plusMin, 1)\n};\n\npp.readToken_lt_gt = function(code) { // '<>'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n if (next === code) {\n size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;\n if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) }\n return this.finishOp(types$1.bitShift, size)\n }\n if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&\n this.input.charCodeAt(this.pos + 3) === 45) {\n // `