UNPKG

@lvce-editor/pty-host

Version:

Terminal process used in Lvce Editor.

1,672 lines (1,619 loc) 73.1 kB
import debugModule from 'debug'; import { spawn } from 'node-pty'; import { Console } from 'node:console'; import { createWriteStream, readFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { fileURLToPath } from 'node:url'; import { Buffer } from 'node:buffer'; class CommandNotFoundError extends Error { constructor(command) { super(`Command not found ${command}`); this.name = 'CommandNotFoundError'; } } const commands = Object.create(null); const register = commandMap => { Object.assign(commands, commandMap); }; const getCommand = key => { return commands[key]; }; const execute = (command, ...args) => { const fn = getCommand(command); if (!fn) { throw new CommandNotFoundError(command); } return fn(...args); }; const normalizeLine = line => { if (line.startsWith('Error: ')) { return line.slice('Error: '.length); } if (line.startsWith('VError: ')) { return line.slice('VError: '.length); } return line; }; const getCombinedMessage = (error, message) => { const stringifiedError = normalizeLine(`${error}`); if (message) { return `${message}: ${stringifiedError}`; } return stringifiedError; }; const NewLine$4 = '\n'; const getNewLineIndex$2 = (string, startIndex = undefined) => { return string.indexOf(NewLine$4, startIndex); }; const mergeStacks = (parent, child) => { if (!child) { return parent; } const parentNewLineIndex = getNewLineIndex$2(parent); const childNewLineIndex = getNewLineIndex$2(child); if (childNewLineIndex === -1) { return parent; } const parentFirstLine = parent.slice(0, parentNewLineIndex); const childRest = child.slice(childNewLineIndex); const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex)); if (parentFirstLine.includes(childFirstLine)) { return parentFirstLine + childRest; } return child; }; class VError extends Error { constructor(error, message) { const combinedMessage = getCombinedMessage(error, message); super(combinedMessage); this.name = 'VError'; if (error instanceof Error) { this.stack = mergeStacks(this.stack, error.stack); } if (error.codeFrame) { // @ts-ignore this.codeFrame = error.codeFrame; } if (error.code) { // @ts-ignore this.code = error.code; } } } class AssertionError extends Error { constructor(message) { super(message); this.name = 'AssertionError'; } } const Object$1 = 1; const Number$1 = 2; const Array$1 = 3; const String$1 = 4; const Boolean = 5; const Function = 6; const Null = 7; const Unknown = 8; const getType = value => { switch (typeof value) { case 'number': return Number$1; case 'function': return Function; case 'string': return String$1; case 'object': if (value === null) { return Null; } if (Array.isArray(value)) { return Array$1; } return Object$1; case 'boolean': return Boolean; default: return Unknown; } }; const object = value => { const type = getType(value); if (type !== Object$1) { throw new AssertionError('expected value to be of type object'); } }; const number = value => { const type = getType(value); if (type !== Number$1) { throw new AssertionError('expected value to be of type number'); } }; const array = value => { const type = getType(value); if (type !== Array$1) { throw new AssertionError('expected value to be of type array'); } }; const string = value => { const type = getType(value); if (type !== String$1) { throw new AssertionError('expected value to be of type string'); } }; const isMessagePort = value => { return value && value instanceof MessagePort; }; const isMessagePortMain = value => { return value && value.constructor && value.constructor.name === 'MessagePortMain'; }; const isOffscreenCanvas = value => { return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas; }; const isInstanceOf = (value, constructorName) => { return value?.constructor?.name === constructorName; }; const isSocket = value => { return isInstanceOf(value, 'Socket'); }; const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket]; const isTransferrable = value => { for (const fn of transferrables) { if (fn(value)) { return true; } } return false; }; const walkValue = (value, transferrables, isTransferrable) => { if (!value) { return; } if (isTransferrable(value)) { transferrables.push(value); return; } if (Array.isArray(value)) { for (const item of value) { walkValue(item, transferrables, isTransferrable); } return; } if (typeof value === 'object') { for (const property of Object.values(value)) { walkValue(property, transferrables, isTransferrable); } return; } }; const getTransferrables = value => { const transferrables = []; walkValue(value, transferrables, isTransferrable); return transferrables; }; const removeValues = (value, toRemove) => { if (!value) { return value; } if (Array.isArray(value)) { const newItems = []; for (const item of value) { if (!toRemove.includes(item)) { newItems.push(removeValues(item, toRemove)); } } return newItems; } if (typeof value === 'object') { const newObject = Object.create(null); for (const [key, property] of Object.entries(value)) { if (!toRemove.includes(property)) { newObject[key] = removeValues(property, toRemove); } } return newObject; } return value; }; // workaround for electron not supporting transferrable objects // as parameters. If the transferrable object is a parameter, in electron // only an empty objected is received in the main process const fixElectronParameters = value => { const transfer = getTransferrables(value); const newValue = removeValues(value, transfer); return { newValue, transfer }; }; const getActualDataElectron = event => { const { data, ports } = event; if (ports.length === 0) { return data; } return { ...data, params: [...ports, ...data.params] }; }; const attachEvents = that => { const handleMessage = (...args) => { const data = that.getData(...args); that.dispatchEvent(new MessageEvent('message', { data })); }; that.onMessage(handleMessage); const handleClose = event => { that.dispatchEvent(new Event('close')); }; that.onClose(handleClose); }; class Ipc extends EventTarget { constructor(rawIpc) { super(); this._rawIpc = rawIpc; attachEvents(this); } } const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE'; const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON'; const ERR_MODULE_NOT_FOUND$1 = 'ERR_MODULE_NOT_FOUND'; const NewLine$3 = '\n'; const joinLines$2 = lines => { return lines.join(NewLine$3); }; const RE_AT$1 = /^\s+at/; const RE_AT_PROMISE_INDEX$1 = /^\s*at async Promise.all \(index \d+\)$/; const isNormalStackLine$1 = line => { return RE_AT$1.test(line) && !RE_AT_PROMISE_INDEX$1.test(line); }; const getDetails$1 = lines => { const index = lines.findIndex(isNormalStackLine$1); if (index === -1) { return { actualMessage: joinLines$2(lines), rest: [] }; } let lastIndex = index - 1; while (++lastIndex < lines.length) { if (!isNormalStackLine$1(lines[lastIndex])) { break; } } return { actualMessage: lines[index - 1], rest: lines.slice(index, lastIndex) }; }; const splitLines$2 = lines => { return lines.split(NewLine$3); }; const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/; const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/; const isMessageCodeBlockStartIndex = line => { return RE_MESSAGE_CODE_BLOCK_START.test(line); }; const isMessageCodeBlockEndIndex = line => { return RE_MESSAGE_CODE_BLOCK_END.test(line); }; const getMessageCodeBlock = stderr => { const lines = splitLines$2(stderr); const startIndex = lines.findIndex(isMessageCodeBlockStartIndex); const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex); const relevantLines = lines.slice(startIndex, endIndex); const relevantMessage = relevantLines.join(' ').slice('Error: '.length); return relevantMessage; }; const isModuleNotFoundMessage = line => { return line.includes('[ERR_MODULE_NOT_FOUND]'); }; const getModuleNotFoundError = stderr => { const lines = splitLines$2(stderr); const messageIndex = lines.findIndex(isModuleNotFoundMessage); const message = lines[messageIndex]; return { message, code: ERR_MODULE_NOT_FOUND$1 }; }; const isModuleNotFoundError = stderr => { if (!stderr) { return false; } return stderr.includes('ERR_MODULE_NOT_FOUND'); }; const isModulesSyntaxError = stderr => { if (!stderr) { return false; } return stderr.includes('SyntaxError: Cannot use import statement outside a module'); }; const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/; const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/; const isUnhelpfulNativeModuleError = stderr => { return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr); }; const getNativeModuleErrorMessage = stderr => { const message = getMessageCodeBlock(stderr); return { message: `Incompatible native node module: ${message}`, code: E_INCOMPATIBLE_NATIVE_MODULE }; }; const getModuleSyntaxError = () => { return { message: `ES Modules are not supported in electron`, code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON }; }; const getHelpfulChildProcessError = (stdout, stderr) => { if (isUnhelpfulNativeModuleError(stderr)) { return getNativeModuleErrorMessage(stderr); } if (isModulesSyntaxError(stderr)) { return getModuleSyntaxError(); } if (isModuleNotFoundError(stderr)) { return getModuleNotFoundError(stderr); } const lines = splitLines$2(stderr); const { actualMessage, rest } = getDetails$1(lines); return { message: actualMessage, code: '', stack: rest }; }; class IpcError extends VError { // @ts-ignore constructor(betterMessage, stdout = '', stderr = '') { if (stdout || stderr) { // @ts-ignore const { message, code, stack } = getHelpfulChildProcessError(stdout, stderr); const cause = new Error(message); // @ts-ignore cause.code = code; cause.stack = stack; super(cause, betterMessage); } else { super(betterMessage); } // @ts-ignore this.name = 'IpcError'; // @ts-ignore this.stdout = stdout; // @ts-ignore this.stderr = stderr; } } const listen$b = ({ messagePort }) => { if (!isMessagePortMain(messagePort)) { throw new IpcError('port must be of type MessagePortMain'); } return messagePort; }; const signal$c = messagePort => { messagePort.start(); }; class IpcChildWithElectronMessagePort extends Ipc { getData = getActualDataElectron; send(message) { this._rawIpc.postMessage(message); } sendAndTransfer(message) { const { newValue, transfer } = fixElectronParameters(message); this._rawIpc.postMessage(newValue, transfer); } dispose() { this._rawIpc.close(); } onMessage(callback) { this._rawIpc.on('message', callback); } onClose(callback) { this._rawIpc.on('close', callback); } } const wrap$j = messagePort => { return new IpcChildWithElectronMessagePort(messagePort); }; const IpcChildWithElectronMessagePort$1 = { __proto__: null, listen: listen$b, signal: signal$c, wrap: wrap$j }; // @ts-ignore const getUtilityProcessPortData = event => { const { data, ports } = event; if (ports.length === 0) { return data; } return { ...data, params: [...ports, ...data.params] }; }; const readyMessage = 'ready'; const listen$a = () => { // @ts-ignore const { parentPort } = process; if (!parentPort) { throw new Error('parent port must be defined'); } return parentPort; }; const signal$b = parentPort => { parentPort.postMessage(readyMessage); }; class IpcChildWithElectronUtilityProcess extends Ipc { getData(event) { return getUtilityProcessPortData(event); } send(message) { this._rawIpc.postMessage(message); } sendAndTransfer(message) { const { newValue, transfer } = fixElectronParameters(message); this._rawIpc.postMessage(newValue, transfer); } dispose() { this._rawIpc.close(); } onClose(callback) { this._rawIpc.on('close', callback); } onMessage(callback) { this._rawIpc.on('message', callback); } } const wrap$i = parentPort => { return new IpcChildWithElectronUtilityProcess(parentPort); }; const IpcChildWithElectronUtilityProcess$1 = { __proto__: null, listen: listen$a, signal: signal$b, wrap: wrap$i }; const getActualData = (message, handle) => { if (handle) { return { ...message, params: [handle, ...message.params] }; } return message; }; const getTransferrablesNode = value => { const transferrables = getTransferrables(value); if (transferrables.length === 0) { throw new Error(`no transferrables found`); } return transferrables[0]; }; const listen$5 = async () => { if (!process.send) { throw new Error('process.send must be defined'); } return process; }; const signal$7 = process => { process.send(readyMessage); }; class IpcChildWithNodeForkedProcess extends Ipc { getData(message, handle) { return getActualData(message, handle); } onClose(callback) { this._rawIpc.on('close', callback); } send(message) { this._rawIpc.send(message); } onMessage(callback) { this._rawIpc.on('message', callback); } sendAndTransfer(message) { const transfer = getTransferrablesNode(message); this._rawIpc.send(message, transfer); } dispose() { // ignore } } const wrap$d = process => { return new IpcChildWithNodeForkedProcess(process); }; const IpcChildWithNodeForkedProcess$1 = { __proto__: null, listen: listen$5, signal: signal$7, wrap: wrap$d }; const Open = 2; const Close = 3; const addListener = (emitter, type, callback) => { if ('addEventListener' in emitter) { emitter.addEventListener(type, callback); } else { emitter.on(type, callback); } }; const removeListener = (emitter, type, callback) => { if ('removeEventListener' in emitter) { emitter.removeEventListener(type, callback); } else { emitter.off(type, callback); } }; const getFirstEvent = (eventEmitter, eventMap) => { const { resolve, promise } = Promise.withResolvers(); const listenerMap = Object.create(null); const cleanup = value => { for (const event of Object.keys(eventMap)) { removeListener(eventEmitter, event, listenerMap[event]); } resolve(value); }; for (const [event, type] of Object.entries(eventMap)) { const listener = event => { cleanup({ type, event }); }; addListener(eventEmitter, event, listener); listenerMap[event] = listener; } return promise; }; // @ts-ignore const getFirstWebSocketEvent = async webSocket => { // @ts-ignore const { WebSocket } = await import('ws'); switch (webSocket.readyState) { case WebSocket.OPEN: return { type: Open, event: undefined }; case WebSocket.CLOSED: return { type: Close, event: undefined }; } // @ts-ignore const { type, event } = await getFirstEvent(webSocket, { open: Open, close: Close }); return { type, event }; }; // @ts-ignore const isWebSocketOpen = async webSocket => { // @ts-ignore const { WebSocket } = await import('ws'); return webSocket.readyState === WebSocket.OPEN; }; // @ts-ignore const serialize = message => { return JSON.stringify(message); }; // @ts-ignore const deserialize = message => { return JSON.parse(message.toString()); }; // @ts-ignore const handleUpgrade$1 = async (...args) => { const module = await Promise.resolve().then(function () { return index; }); // @ts-ignore return module.handleUpgrade(...args); }; const listen$1$1 = async ({ request, handle }) => { if (!request) { throw new IpcError('request must be defined'); } if (!handle) { throw new IpcError('handle must be defined'); } const webSocket = await handleUpgrade$1(request, handle); webSocket.pause(); if (!(await isWebSocketOpen(webSocket))) { await getFirstWebSocketEvent(webSocket); } return webSocket; }; const signal$4 = webSocket => { webSocket.resume(); }; const wrap$9 = webSocket => { return { webSocket, /** * @type {any} */ wrappedListener: undefined, // @ts-ignore on(event, listener) { switch (event) { case 'message': // @ts-ignore const wrappedListener = message => { const data = deserialize(message); const event = { data, target: this }; listener(event); }; webSocket.on('message', wrappedListener); break; case 'close': webSocket.on('close', listener); break; default: throw new Error('unknown event listener type'); } }, // @ts-ignore off(event, listener) { this.webSocket.off(event, listener); }, // @ts-ignore send(message) { const stringifiedMessage = serialize(message); this.webSocket.send(stringifiedMessage); }, dispose() { this.webSocket.close(); }, start() { throw new Error('start method is deprecated'); } }; }; const IpcChildWithWebSocket = { __proto__: null, listen: listen$1$1, signal: signal$4, wrap: wrap$9 }; const Two = '2.0'; const create$4 = (method, params) => { return { jsonrpc: Two, method, params }; }; const callbacks = Object.create(null); const set$1 = (id, fn) => { callbacks[id] = fn; }; const get$1 = id => { return callbacks[id]; }; const remove$1 = id => { delete callbacks[id]; }; let id = 0; const create$3 = () => { return ++id; }; const registerPromise = () => { const id = create$3(); const { resolve, promise } = Promise.withResolvers(); set$1(id, resolve); return { id, promise }; }; const create$2 = (method, params) => { const { id, promise } = registerPromise(); const message = { jsonrpc: Two, method, params, id }; return { message, promise }; }; class JsonRpcError extends Error { constructor(message) { super(message); this.name = 'JsonRpcError'; } } const NewLine$2 = '\n'; const DomException = 'DOMException'; const ReferenceError$1 = 'ReferenceError'; const SyntaxError$1 = 'SyntaxError'; const TypeError$1 = 'TypeError'; const getErrorConstructor = (message, type) => { if (type) { switch (type) { case DomException: return DOMException; case TypeError$1: return TypeError; case SyntaxError$1: return SyntaxError; case ReferenceError$1: return ReferenceError; default: return Error; } } if (message.startsWith('TypeError: ')) { return TypeError; } if (message.startsWith('SyntaxError: ')) { return SyntaxError; } if (message.startsWith('ReferenceError: ')) { return ReferenceError; } return Error; }; const constructError = (message, type, name) => { const ErrorConstructor = getErrorConstructor(message, type); if (ErrorConstructor === DOMException && name) { return new ErrorConstructor(message, name); } if (ErrorConstructor === Error) { const error = new Error(message); if (name && name !== 'VError') { error.name = name; } return error; } return new ErrorConstructor(message); }; const joinLines$1 = lines => { return lines.join(NewLine$2); }; const splitLines$1 = lines => { return lines.split(NewLine$2); }; const getCurrentStack = () => { const stackLinesToSkip = 3; const currentStack = joinLines$1(splitLines$1(new Error().stack || '').slice(stackLinesToSkip)); return currentStack; }; const getNewLineIndex$1 = (string, startIndex = undefined) => { return string.indexOf(NewLine$2, startIndex); }; const getParentStack = error => { let parentStack = error.stack || error.data || error.message || ''; if (parentStack.startsWith(' at')) { parentStack = error.message + NewLine$2 + parentStack; } return parentStack; }; const MethodNotFound = -32601; const Custom = -32001; const restoreJsonRpcError = error => { const currentStack = getCurrentStack(); if (error && error instanceof Error) { if (typeof error.stack === 'string') { error.stack = error.stack + NewLine$2 + currentStack; } return error; } if (error && error.code && error.code === MethodNotFound) { const restoredError = new JsonRpcError(error.message); const parentStack = getParentStack(error); restoredError.stack = parentStack + NewLine$2 + currentStack; return restoredError; } if (error && error.message) { const restoredError = constructError(error.message, error.type, error.name); if (error.data) { if (error.data.stack && error.data.type && error.message) { restoredError.stack = error.data.type + ': ' + error.message + NewLine$2 + error.data.stack + NewLine$2 + currentStack; } else if (error.data.stack) { restoredError.stack = error.data.stack; } if (error.data.codeFrame) { // @ts-ignore restoredError.codeFrame = error.data.codeFrame; } if (error.data.code) { // @ts-ignore restoredError.code = error.data.code; } if (error.data.type) { // @ts-ignore restoredError.name = error.data.type; } } else { if (error.stack) { const lowerStack = restoredError.stack || ''; // @ts-ignore const indexNewLine = getNewLineIndex$1(lowerStack); const parentStack = getParentStack(error); // @ts-ignore restoredError.stack = parentStack + lowerStack.slice(indexNewLine); } if (error.codeFrame) { // @ts-ignore restoredError.codeFrame = error.codeFrame; } } return restoredError; } if (typeof error === 'string') { return new Error(`JsonRpc Error: ${error}`); } return new Error(`JsonRpc Error: ${error}`); }; const unwrapJsonRpcResult = responseMessage => { if ('error' in responseMessage) { const restoredError = restoreJsonRpcError(responseMessage.error); throw restoredError; } if ('result' in responseMessage) { return responseMessage.result; } throw new JsonRpcError('unexpected response message'); }; const warn$1 = (...args) => { console.warn(...args); }; const resolve = (id, response) => { const fn = get$1(id); if (!fn) { console.log(response); warn$1(`callback ${id} may already be disposed`); return; } fn(response); remove$1(id); }; const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND'; const getErrorType = prettyError => { if (prettyError && prettyError.type) { return prettyError.type; } if (prettyError && prettyError.constructor && prettyError.constructor.name) { return prettyError.constructor.name; } return undefined; }; const isAlreadyStack = line => { return line.trim().startsWith('at '); }; const getStack = prettyError => { const stackString = prettyError.stack || ''; const newLineIndex = stackString.indexOf('\n'); if (newLineIndex !== -1 && !isAlreadyStack(stackString.slice(0, newLineIndex))) { return stackString.slice(newLineIndex + 1); } return stackString; }; const getErrorProperty = (error, prettyError) => { if (error && error.code === E_COMMAND_NOT_FOUND) { return { code: MethodNotFound, message: error.message, data: error.stack }; } return { code: Custom, message: prettyError.message, data: { stack: getStack(prettyError), codeFrame: prettyError.codeFrame, type: getErrorType(prettyError), code: prettyError.code, name: prettyError.name } }; }; const create$1$1 = (id, error) => { return { jsonrpc: Two, id, error }; }; const getErrorResponse = (id, error, preparePrettyError, logError) => { const prettyError = preparePrettyError(error); logError(error, prettyError); const errorProperty = getErrorProperty(error, prettyError); return create$1$1(id, errorProperty); }; const create$5 = (message, result) => { return { jsonrpc: Two, id: message.id, result: result ?? null }; }; const getSuccessResponse = (message, result) => { const resultProperty = result ?? null; return create$5(message, resultProperty); }; const getErrorResponseSimple = (id, error) => { return { jsonrpc: Two, id, error: { code: Custom, // @ts-ignore message: error.message, data: error } }; }; const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => { try { const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params); return getSuccessResponse(message, result); } catch (error) { if (ipc.canUseSimpleErrorResponse) { return getErrorResponseSimple(message.id, error); } return getErrorResponse(message.id, error, preparePrettyError, logError); } }; const defaultPreparePrettyError = error => { return error; }; const defaultLogError = () => { // ignore }; const defaultRequiresSocket = () => { return false; }; const defaultResolve = resolve; // TODO maybe remove this in v6 or v7, only accept options object to simplify the code const normalizeParams = args => { if (args.length === 1) { const options = args[0]; return { ipc: options.ipc, message: options.message, execute: options.execute, resolve: options.resolve || defaultResolve, preparePrettyError: options.preparePrettyError || defaultPreparePrettyError, logError: options.logError || defaultLogError, requiresSocket: options.requiresSocket || defaultRequiresSocket }; } return { ipc: args[0], message: args[1], execute: args[2], resolve: args[3], preparePrettyError: args[4], logError: args[5], requiresSocket: args[6] }; }; const handleJsonRpcMessage = async (...args) => { const options = normalizeParams(args); const { message, ipc, execute, resolve, preparePrettyError, logError, requiresSocket } = options; if ('id' in message) { if ('method' in message) { const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket); try { ipc.send(response); } catch (error) { const errorResponse = getErrorResponse(message.id, error, preparePrettyError, logError); ipc.send(errorResponse); } return; } resolve(message.id, message); return; } if ('method' in message) { await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket); return; } throw new JsonRpcError('unexpected message'); }; const invokeHelper = async (ipc, method, params, useSendAndTransfer) => { const { message, promise } = create$2(method, params); if (useSendAndTransfer && ipc.sendAndTransfer) { ipc.sendAndTransfer(message); } else { ipc.send(message); } const responseMessage = await promise; return unwrapJsonRpcResult(responseMessage); }; const send = (transport, method, ...params) => { const message = create$4(method, params); transport.send(message); }; const invoke = (ipc, method, ...params) => { return invokeHelper(ipc, method, params, false); }; const invokeAndTransfer = (ipc, method, ...params) => { return invokeHelper(ipc, method, params, true); }; const createRpc = ipc => { const rpc = { // @ts-ignore ipc, /** * @deprecated */ send(method, ...params) { send(ipc, method, ...params); }, invoke(method, ...params) { return invoke(ipc, method, ...params); }, invokeAndTransfer(method, ...params) { return invokeAndTransfer(ipc, method, ...params); }, async dispose() { await ipc?.dispose(); } }; return rpc; }; const requiresSocket$1 = () => { return false; }; const preparePrettyError = error => { return error; }; const logError = () => { // handled by renderer worker }; const handleMessage = event => { const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket$1; const actualExecute = event?.target?.execute || execute; return handleJsonRpcMessage(event.target, event.data, actualExecute, resolve, preparePrettyError, logError, actualRequiresSocket); }; const handleIpc = ipc => { if ('addEventListener' in ipc) { ipc.addEventListener('message', handleMessage); } else if ('on' in ipc) { // deprecated ipc.on('message', handleMessage); } }; const listen$2 = async (module, options) => { const rawIpc = await module.listen(options); if (module.signal) { module.signal(rawIpc); } const ipc = module.wrap(rawIpc); return ipc; }; const create$k = async ({ commandMap, messagePort, requiresSocket }) => { // TODO create a commandMap per rpc instance register(commandMap); const ipc = await listen$2(IpcChildWithElectronMessagePort$1, { messagePort }); if (requiresSocket) { ipc.requiresSocket = requiresSocket; } handleIpc(ipc); const rpc = createRpc(ipc); return rpc; }; const ElectronMessagePortRpcClient = { __proto__: null, create: create$k }; const create$j = async ({ commandMap }) => { // TODO create a commandMap per rpc instance register(commandMap); const ipc = await listen$2(IpcChildWithElectronUtilityProcess$1); handleIpc(ipc); const rpc = createRpc(ipc); return rpc; }; const ElectronUtilityProcessRpcClient = { __proto__: null, create: create$j }; const create$a = async ({ commandMap }) => { // TODO create a commandMap per rpc instance register(commandMap); const ipc = await listen$2(IpcChildWithNodeForkedProcess$1); handleIpc(ipc); const rpc = createRpc(ipc); return rpc; }; const NodeForkedProcessRpcClient = { __proto__: null, create: create$a }; const create$8 = async ({ commandMap, request, handle, requiresSocket }) => { // TODO create a commandMap per rpc instance register(commandMap); const ipc = await listen$2(IpcChildWithWebSocket, { request, handle }); if (requiresSocket) { ipc.requiresSocket = requiresSocket; } handleIpc(ipc); const rpc = createRpc(ipc); return rpc; }; const NodeWebSocketRpcClient = { __proto__: null, create: create$8 }; const METHODS_THAT_REQUIRE_SOCKET = new Set(['Terminal.create']); const requiresSocket = method => { return METHODS_THAT_REQUIRE_SOCKET.has(method); }; const handleElectronMessagePort = async messagePort => { object(messagePort); await ElectronMessagePortRpcClient.create({ commandMap: {}, messagePort, requiresSocket: requiresSocket }); }; const NodeWorker = 1; const NodeForkedProcess = 2; const WebSocket = 3; const ElectronUtilityProcess = 4; const ElectronMessagePort = 5; const NodeMessagePort = 6; const Auto = () => { const { argv } = process; if (argv.includes('--ipc-type=node-worker')) { return NodeWorker; } if (argv.includes('--ipc-type=node-forked-process')) { return NodeForkedProcess; } if (argv.includes('--ipc-type=electron-utility-process')) { return ElectronUtilityProcess; } throw new Error(`[pty-host] unknown ipc type`); }; const getModule = method => { switch (method) { case NodeForkedProcess: return NodeForkedProcessRpcClient; case WebSocket: return NodeWebSocketRpcClient; case ElectronUtilityProcess: return ElectronUtilityProcessRpcClient; case ElectronMessagePort: return ElectronMessagePortRpcClient; default: throw new Error('unexpected ipc type'); } }; const listen$1 = async ({ method, ...params }) => { const module = getModule(method); // @ts-ignore const rpc = await module.create(params); return rpc; }; const handleNodeMessagePort = async messagePort => { await listen$1({ method: NodeMessagePort, messagePort }); }; const handleWebSocket = async (handle, request) => { object(handle); object(request); await NodeWebSocketRpcClient.create({ commandMap: {}, handle, request, requiresSocket: requiresSocket }); }; const debug = debugModule('pty-host'); class DataEvent extends Event { constructor(data) { super('data'); this.data = data; } } class ExitEvent extends Event { constructor(data) { super('exit'); this.data = data; } } class Pty extends EventTarget { /** * * @param {import('node-pty').IPty} pty */ constructor(pty) { super(); this.pty = pty; const handleData = data => { this.dispatchEvent(new DataEvent(data)); }; const handleExit = data => { this.dispatchEvent(new ExitEvent(data)); }; this.pty.onData(handleData); this.pty.onExit(handleExit); } resize(columns, rows) { this.pty.resize(columns, rows); } dispose() { this.pty.kill(); } write(data) { this.pty.write(data); } } /** * * @param {*} param0 * @returns {any} */ const create$1 = ({ cwd, command, args } = {}) => { try { string(cwd); string(command); array(args); const pty = spawn(command, args, { encoding: null, cwd // cols: 10, // rows: 10, }); const wrapped = new Pty(pty); return wrapped; } catch (error) { throw new VError(error, `Failed to create terminal`); } }; const state$1 = { ptyMap: Object.create(null) }; const set = (id, pty) => { state$1.ptyMap[id] = pty; }; const get = id => { return state$1.ptyMap[id]; }; const remove = id => { delete state$1.ptyMap[id]; }; // TODO maybe merge pty and pty controller const create = (ipc, id, cwd, command, args) => { number(id); string(cwd); string(command); array(args); object(ipc); debug(`create ${id} ${cwd}`); // @ts-ignore const pty = create$1({ cwd, command, args }); const handleData = event => { ipc.send({ jsonrpc: '2.0', method: 'Viewlet.send', params: [id, 'handleData', event.data] }); }; pty.addEventListener('data', handleData); set(id, pty); }; const write = (id, data) => { const pty = get(id); if (!pty) { throw new Error(`pty ${id} not found`); } pty.write(data); }; const resize = (id, columns, rows) => { const pty = get(id); if (!pty) { throw new Error(`pty ${id} not found`); } pty.resize(columns, rows); }; const dispose = id => { const pty = get(id); if (!pty) { throw new Error(`pty ${id} not found`); } pty.dispose(); remove(id); }; const HandleElectronMessagePort = 'HandleElectronMessagePort.handleElectronMessagePort'; const HandleNodeMessagePort = 'HandleNodeMessagePort.handleNodeMessagePort'; const HandleWebSocket = 'HandleWebSocket.handleWebSocket'; const TerminalCreate = 'Terminal.create'; const TerminalResize = 'Terminal.resize'; const TerminalWrite = 'Terminal.write'; const TerminalDispose = 'Terminal.dispose'; const commandMap = { [HandleElectronMessagePort]: handleElectronMessagePort, [HandleNodeMessagePort]: handleNodeMessagePort, [HandleWebSocket]: handleWebSocket, [TerminalCreate]: create, [TerminalResize]: resize, [TerminalWrite]: write, [TerminalDispose]: dispose }; const listen = async () => { await listen$1({ method: Auto() }); }; const NewLine$1 = '\n'; const Error$1 = 1; const Success = 0; /** * * @param {string} string * @param {number|undefined} startIndex * @returns */ const getNewLineIndex = (string, startIndex = undefined) => { return string.indexOf(NewLine$1, startIndex); }; const EPIPE = 'EPIPE'; const ERR_IPC_CHANNEL_CLOSED = 'ERR_IPC_CHANNEL_CLOSED'; const exit = code => { process.exit(code); }; const setExitCode = exitCode => { process.exitCode = exitCode; }; const isConnected = () => { return process.connected; }; const isIgnoredError = error => { if (error && error.code === EPIPE && !process.connected) { // parent process is disposed, ignore return true; } if (error && error.code === ERR_IPC_CHANNEL_CLOSED && !isConnected()) { // parent process is disposed, ignore return true; } return false; }; // TODO mock this module when used in unit tests const state = { console: undefined }; const createConsole = () => { const logFile = `${tmpdir()}/log-terminal-process.txt`; const writeStream = createWriteStream(logFile); const logger = new Console(writeStream); return logger; }; const getOrCreateLogger = () => { if (!state.console) { state.console = createConsole(); } return state.console; }; const info = (...args) => { const logger = getOrCreateLogger(); logger.info(...args); console.info(...args); }; const error = (...args) => { const logger = getOrCreateLogger(); logger.error(...args); console.error(...args); }; var lib$1 = {}; var picocolors = {exports: {}}; var hasRequiredPicocolors; function requirePicocolors () { if (hasRequiredPicocolors) return picocolors.exports; hasRequiredPicocolors = 1; let p = process || {}, argv = p.argv || [], env = p.env || {}; let isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI); let formatter = (open, close, replace = open) => input => { let string = "" + input, index = string.indexOf(close, open.length); return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close; }; let replaceClose = (string, close, replace, index) => { let result = "", cursor = 0; do { result += string.substring(cursor, index) + replace; cursor = index + close.length; index = string.indexOf(close, cursor); } while (~index); return result + string.substring(cursor); }; let createColors = (enabled = isColorSupported) => { let f = enabled ? formatter : () => String; return { isColorSupported: enabled, reset: f("\x1b[0m", "\x1b[0m"), bold: f("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m"), dim: f("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m"), italic: f("\x1b[3m", "\x1b[23m"), underline: f("\x1b[4m", "\x1b[24m"), inverse: f("\x1b[7m", "\x1b[27m"), hidden: f("\x1b[8m", "\x1b[28m"), strikethrough: f("\x1b[9m", "\x1b[29m"), black: f("\x1b[30m", "\x1b[39m"), red: f("\x1b[31m", "\x1b[39m"), green: f("\x1b[32m", "\x1b[39m"), yellow: f("\x1b[33m", "\x1b[39m"), blue: f("\x1b[34m", "\x1b[39m"), magenta: f("\x1b[35m", "\x1b[39m"), cyan: f("\x1b[36m", "\x1b[39m"), white: f("\x1b[37m", "\x1b[39m"), gray: f("\x1b[90m", "\x1b[39m"), bgBlack: f("\x1b[40m", "\x1b[49m"), bgRed: f("\x1b[41m", "\x1b[49m"), bgGreen: f("\x1b[42m", "\x1b[49m"), bgYellow: f("\x1b[43m", "\x1b[49m"), bgBlue: f("\x1b[44m", "\x1b[49m"), bgMagenta: f("\x1b[45m", "\x1b[49m"), bgCyan: f("\x1b[46m", "\x1b[49m"), bgWhite: f("\x1b[47m", "\x1b[49m"), blackBright: f("\x1b[90m", "\x1b[39m"), redBright: f("\x1b[91m", "\x1b[39m"), greenBright: f("\x1b[92m", "\x1b[39m"), yellowBright: f("\x1b[93m", "\x1b[39m"), blueBright: f("\x1b[94m", "\x1b[39m"), magentaBright: f("\x1b[95m", "\x1b[39m"), cyanBright: f("\x1b[96m", "\x1b[39m"), whiteBright: f("\x1b[97m", "\x1b[39m"), bgBlackBright: f("\x1b[100m", "\x1b[49m"), bgRedBright: f("\x1b[101m", "\x1b[49m"), bgGreenBright: f("\x1b[102m", "\x1b[49m"), bgYellowBright: f("\x1b[103m", "\x1b[49m"), bgBlueBright: f("\x1b[104m", "\x1b[49m"), bgMagentaBright: f("\x1b[105m", "\x1b[49m"), bgCyanBright: f("\x1b[106m", "\x1b[49m"), bgWhiteBright: f("\x1b[107m", "\x1b[49m") }; }; picocolors.exports = createColors(); picocolors.exports.createColors = createColors; return picocolors.exports; } var jsTokens = {}; var hasRequiredJsTokens; function requireJsTokens () { if (hasRequiredJsTokens) return jsTokens; hasRequiredJsTokens = 1; // Copyright 2014, 2015, 2016, 2017, 2018 Simon Lydell // License: MIT. (See LICENSE.) Object.defineProperty(jsTokens, "__esModule", { value: true }); // This regex comes from regex.coffee, and is inserted here by generate-index.js // (run `npm run build`). jsTokens.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyus]{1,6}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g; jsTokens.matchToToken = function (match) { var token = { type: "invalid", value: match[0], closed: undefined }; if (match[1]) token.type = "string", token.closed = !!(match[3] || match[4]);else if (match[5]) token.type = "comment";else if (match[6]) token.type = "comment", token.closed = !!match[7];else if (match[8]) token.type = "regex";else if (match[9]) token.type = "number";else if (match[10]) token.type = "name";else if (match[11]) token.type = "punctuator";else if (match[12]) token.type = "whitespace"; return token; }; return jsTokens; } var lib = {}; var identifier = {}; var hasRequiredIdentifier; function requireIdentifier () { if (hasRequiredIdentifier) return identifier; hasRequiredIdentifier = 1; Object.defineProperty(identifier, "__esModule", { value: true }); identifier.isIdentifierChar = isIdentifierChar; identifier.isIdentifierName = isIdentifierName; identifier.isIdentifierStart = isIdentifierStart; let 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-\u1c8a\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-\ua7cd\ua7d0\ua7d1\ua7d3\ua7d5-\ua7dc\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"; let nonASCIIidentifierChars = "\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\u0897-\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\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\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\uff65"; const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48