const state$2 = {
  commands: Object.create(null),
};

const registerCommand = (key, fn) => {
  state$2.commands[key] = fn;
};

const registerCommands = (commandMap) => {
  for (const [key, value] of Object.entries(commandMap)) {
    registerCommand(key, value);
  }
};

const getCommand = (key) => {
  return state$2.commands[key]
};

const execute = (command, ...args) => {
  const fn = getCommand(command);
  return fn(...args)
};

class AssertionError extends Error {
  constructor(message) {
    super(message);
    this.name = 'AssertionError';
  }
}

const getType = (value) => {
  switch (typeof value) {
    case 'number':
      return 'number'
    case 'function':
      return 'function'
    case 'string':
      return 'string'
    case 'object':
      if (value === null) {
        return 'null'
      }
      if (Array.isArray(value)) {
        return 'array'
      }
      return 'object'
    case 'boolean':
      return 'boolean'
    default:
      return 'unknown'
  }
};

const object = (value) => {
  const type = getType(value);
  if (type !== 'object') {
    throw new AssertionError('expected value to be of type object')
  }
};

const number = (value) => {
  const type = getType(value);
  if (type !== 'number') {
    throw new AssertionError('expected value to be of type number')
  }
};

const string = (value) => {
  const type = getType(value);
  if (type !== 'string') {
    throw new AssertionError('expected value to be of type string')
  }
};

const fn = (value) => {
  const type = getType(value);
  if (type !== 'function') {
    throw new AssertionError('expected value to be of type function')
  }
};

/**
 *
 * @param {string} string
 * @param {number|undefined} startIndex
 * @returns
 */
const getNewLineIndex = (string, startIndex = undefined) => {
  return string.indexOf('\n', startIndex)
};

const normalizeLine = (line) => {
  if (line.startsWith('Error: ')) {
    return line.slice(`Error: `.length)
  }
  if (line.startsWith('VError: ')) {
    return line.slice(`VError: `.length)
  }
  return line
};

const mergeStacks = (parent, child) => {
  if (!child) {
    return parent
  }
  const parentNewLineIndex = getNewLineIndex(parent);
  const childNewLineIndex = getNewLineIndex(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
};

const getCombinedMessage = (error, message) => {
  const stringifiedError = normalizeLine(`${error}`);
  if (message) {
    return `${message}: ${stringifiedError}`
  }
  return stringifiedError
};

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) {
      this.codeFrame = error.codeFrame;
    }
    if (error.code) {
      this.code = error.code;
    }
  }
}

/**
 *
 * @param {string|undefined} lines
 * @returns string[]
 */
const splitLines = (lines) => {
  if (!lines) {
    return []
  }
  return lines.split('\n')
};

const RE_AT = /^    at /;
const RE_JUST_PATH = /^(?:\/|\\).*\:\d+$/;

const isStackLine = (line) => {
  return RE_AT.test(line)
};

const isJustPath = (line) => {
  return RE_JUST_PATH.test(line)
};

const getModulesErrorStack = (stderr) => {
  const lines = splitLines(stderr);
  let startIndex = -1;
  const extraLines = [];
  for (let i = 0; i < lines.length; i++) {
    const line = lines[i];
    if (isJustPath(line)) {
      extraLines.push(`    at ${line}`);
      break
    }
  }
  for (let i = 0; i < lines.length; i++) {
    const line = lines[i];
    if (isStackLine(line)) {
      startIndex = i;
      break
    }
  }
  if (startIndex === -1) {
    return []
  }
  let endIndex = -1;
  for (let i = startIndex + 1; i < lines.length; i++) {
    const line = lines[i];
    if (!isStackLine(line)) {
      endIndex = i;
      break
    }
  }
  if (endIndex === -1) {
    endIndex = lines.length - 1;
  }
  const stackLines = lines.slice(startIndex, endIndex);
  const stack = [lines[startIndex - 1], ...extraLines, ...stackLines];
  return stack
};

const joinLines = (lines) => {
  return lines.join('\n')
};

const cleanImportSyntaxError = (error) => {
  const cleanStackLines = getModulesErrorStack(error.stack);
  const cleanError = new SyntaxError(error.message);
  const currentStack = joinLines(splitLines(new Error().stack).slice(3));
  const cleanStack = joinLines(cleanStackLines);
  const mergedStack = cleanStack + '\n' + currentStack;
  cleanError.stack = mergedStack;
  return cleanError
};

const cleanImportError = (error) => {
  if (error && error instanceof SyntaxError) {
    return cleanImportSyntaxError(error)
  }
  return error
};

const importScript = async (path) => {
  try {
    const module = await import(path);
    return module
  } catch (error) {
    const cleanError = cleanImportError(error);
    throw new VError(cleanError, `Failed to load ${path}`)
  }
};

const loadFile = async (path) => {
  try {
    string(path);
    const module = await importScript(path);
    if (module && module.commandMap) {
      const commandMap = module.commandMap;
      registerCommands(commandMap);
    } else {
      throw new Error(`missing export const execute function`)
    }
  } catch (error) {
    throw new VError(error, `Failed to load ${path}`)
  }
};

const commandMap = {
  'LoadFile.loadFile': loadFile,
};

const state$1 = {
  id: 0,
};

const create$2 = () => {
  return ++state$1.id
};

const state = {
  callbacks: Object.create(null),
};

const registerPromise = () => {
  const id = create$2();
  const promise = new Promise((resolve, reject) => {
    state.callbacks[id] = {
      resolve,
      reject,
    };
  });
  return { id, promise }
};

const resolve = (id, args) => {
  number(id);
  if (!(id in state.callbacks)) {
    console.log(args);
    console.warn(`callback ${id} may already be disposed`);
    return
  }
  state.callbacks[id].resolve(args);
  delete state.callbacks[id];
};

const MethodNotFound = -32601;
const Custom = -32001;

const Two = '2.0';

class HTTPError extends Error {
  constructor(response, request, options) {
    const code = response.status || response.status === 0 ? response.status : "";
    const title = response.statusText || "";
    const status = `${code} ${title}`.trim();
    const reason = status ? `status code ${status}` : "an unknown error";
    super(`Request failed with ${reason}`);
    Object.defineProperty(this, "response", {
      enumerable: true,
      configurable: true,
      writable: true,
      value: void 0
    });
    Object.defineProperty(this, "request", {
      enumerable: true,
      configurable: true,
      writable: true,
      value: void 0
    });
    Object.defineProperty(this, "options", {
      enumerable: true,
      configurable: true,
      writable: true,
      value: void 0
    });
    this.name = "HTTPError";
    this.response = response;
    this.request = request;
    this.options = options;
  }
}
class TimeoutError extends Error {
  constructor(request) {
    super("Request timed out");
    Object.defineProperty(this, "request", {
      enumerable: true,
      configurable: true,
      writable: true,
      value: void 0
    });
    this.name = "TimeoutError";
    this.request = request;
  }
}
const isObject = (value) => value !== null && typeof value === "object";
const validateAndMerge = (...sources) => {
  for (const source of sources) {
    if ((!isObject(source) || Array.isArray(source)) && typeof source !== "undefined") {
      throw new TypeError("The `options` argument must be an object");
    }
  }
  return deepMerge({}, ...sources);
};
const mergeHeaders = (source1 = {}, source2 = {}) => {
  const result = new globalThis.Headers(source1);
  const isHeadersInstance = source2 instanceof globalThis.Headers;
  const source = new globalThis.Headers(source2);
  for (const [key, value] of source.entries()) {
    if (isHeadersInstance && value === "undefined" || value === void 0) {
      result.delete(key);
    } else {
      result.set(key, value);
    }
  }
  return result;
};
const deepMerge = (...sources) => {
  let returnValue = {};
  let headers = {};
  for (const source of sources) {
    if (Array.isArray(source)) {
      if (!Array.isArray(returnValue)) {
        returnValue = [];
      }
      returnValue = [...returnValue, ...source];
    } else if (isObject(source)) {
      for (let [key, value] of Object.entries(source)) {
        if (isObject(value) && key in returnValue) {
          value = deepMerge(returnValue[key], value);
        }
        returnValue = {...returnValue, [key]: value};
      }
      if (isObject(source.headers)) {
        headers = mergeHeaders(headers, source.headers);
        returnValue.headers = headers;
      }
    }
  }
  return returnValue;
};
const supportsRequestStreams = (() => {
  let duplexAccessed = false;
  let hasContentType = false;
  const supportsReadableStream = typeof globalThis.ReadableStream === "function";
  const supportsRequest = typeof globalThis.Request === "function";
  if (supportsReadableStream && supportsRequest) {
    hasContentType = new globalThis.Request("https://a.com", {
      body: new globalThis.ReadableStream(),
      method: "POST",
      get duplex() {
        duplexAccessed = true;
        return "half";
      }
    }).headers.has("Content-Type");
  }
  return duplexAccessed && !hasContentType;
})();
const supportsAbortController = typeof globalThis.AbortController === "function";
const supportsResponseStreams = typeof globalThis.ReadableStream === "function";
const supportsFormData = typeof globalThis.FormData === "function";
const requestMethods = ["get", "post", "put", "patch", "head", "delete"];
const responseTypes = {
  json: "application/json",
  text: "text/*",
  formData: "multipart/form-data",
  arrayBuffer: "*/*",
  blob: "*/*"
};
const maxSafeTimeout = 2147483647;
const stop = Symbol("stop");
const normalizeRequestMethod = (input) => requestMethods.includes(input) ? input.toUpperCase() : input;
const retryMethods = ["get", "put", "head", "delete", "options", "trace"];
const retryStatusCodes = [408, 413, 429, 500, 502, 503, 504];
const retryAfterStatusCodes = [413, 429, 503];
const defaultRetryOptions = {
  limit: 2,
  methods: retryMethods,
  statusCodes: retryStatusCodes,
  afterStatusCodes: retryAfterStatusCodes,
  maxRetryAfter: Number.POSITIVE_INFINITY,
  backoffLimit: Number.POSITIVE_INFINITY
};
const normalizeRetryOptions = (retry = {}) => {
  if (typeof retry === "number") {
    return {
      ...defaultRetryOptions,
      limit: retry
    };
  }
  if (retry.methods && !Array.isArray(retry.methods)) {
    throw new Error("retry.methods must be an array");
  }
  if (retry.statusCodes && !Array.isArray(retry.statusCodes)) {
    throw new Error("retry.statusCodes must be an array");
  }
  return {
    ...defaultRetryOptions,
    ...retry,
    afterStatusCodes: retryAfterStatusCodes
  };
};
async function timeout(request, abortController, options) {
  return new Promise((resolve, reject) => {
    const timeoutId = setTimeout(() => {
      if (abortController) {
        abortController.abort();
      }
      reject(new TimeoutError(request));
    }, options.timeout);
    void options.fetch(request).then(resolve).catch(reject).then(() => {
      clearTimeout(timeoutId);
    });
  });
}
const isDomExceptionSupported = Boolean(globalThis.DOMException);
function composeAbortError(signal) {
  var _a, _b;
  if (isDomExceptionSupported) {
    return new DOMException((_a = signal == null ? void 0 : signal.reason) != null ? _a : "The operation was aborted.", "AbortError");
  }
  const error = new Error((_b = signal == null ? void 0 : signal.reason) != null ? _b : "The operation was aborted.");
  error.name = "AbortError";
  return error;
}
async function delay(ms, {signal}) {
  return new Promise((resolve, reject) => {
    if (signal) {
      if (signal.aborted) {
        reject(composeAbortError(signal));
        return;
      }
      signal.addEventListener("abort", handleAbort, {once: true});
    }
    function handleAbort() {
      reject(composeAbortError(signal));
      clearTimeout(timeoutId);
    }
    const timeoutId = setTimeout(() => {
      signal == null ? void 0 : signal.removeEventListener("abort", handleAbort);
      resolve();
    }, ms);
  });
}
class Ky {
  static create(input, options) {
    const ky2 = new Ky(input, options);
    const fn = async () => {
      if (ky2._options.timeout > maxSafeTimeout) {
        throw new RangeError(`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`);
      }
      await Promise.resolve();
      let response = await ky2._fetch();
      for (const hook of ky2._options.hooks.afterResponse) {
        const modifiedResponse = await hook(ky2.request, ky2._options, ky2._decorateResponse(response.clone()));
        if (modifiedResponse instanceof globalThis.Response) {
          response = modifiedResponse;
        }
      }
      ky2._decorateResponse(response);
      if (!response.ok && ky2._options.throwHttpErrors) {
        let error = new HTTPError(response, ky2.request, ky2._options);
        for (const hook of ky2._options.hooks.beforeError) {
          error = await hook(error);
        }
        throw error;
      }
      if (ky2._options.onDownloadProgress) {
        if (typeof ky2._options.onDownloadProgress !== "function") {
          throw new TypeError("The `onDownloadProgress` option must be a function");
        }
        if (!supportsResponseStreams) {
          throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");
        }
        return ky2._stream(response.clone(), ky2._options.onDownloadProgress);
      }
      return response;
    };
    const isRetriableMethod = ky2._options.retry.methods.includes(ky2.request.method.toLowerCase());
    const result = isRetriableMethod ? ky2._retry(fn) : fn();
    for (const [type, mimeType] of Object.entries(responseTypes)) {
      result[type] = async () => {
        ky2.request.headers.set("accept", ky2.request.headers.get("accept") || mimeType);
        const awaitedResult = await result;
        const response = awaitedResult.clone();
        if (type === "json") {
          if (response.status === 204) {
            return "";
          }
          const arrayBuffer = await response.clone().arrayBuffer();
          const responseSize = arrayBuffer.byteLength;
          if (responseSize === 0) {
            return "";
          }
          if (options.parseJson) {
            return options.parseJson(await response.text());
          }
        }
        return response[type]();
      };
    }
    return result;
  }
  constructor(input, options = {}) {
    var _a, _b, _c;
    Object.defineProperty(this, "request", {
      enumerable: true,
      configurable: true,
      writable: true,
      value: void 0
    });
    Object.defineProperty(this, "abortController", {
      enumerable: true,
      configurable: true,
      writable: true,
      value: void 0
    });
    Object.defineProperty(this, "_retryCount", {
      enumerable: true,
      configurable: true,
      writable: true,
      value: 0
    });
    Object.defineProperty(this, "_input", {
      enumerable: true,
      configurable: true,
      writable: true,
      value: void 0
    });
    Object.defineProperty(this, "_options", {
      enumerable: true,
      configurable: true,
      writable: true,
      value: void 0
    });
    this._input = input;
    this._options = {
      credentials: this._input.credentials || "same-origin",
      ...options,
      headers: mergeHeaders(this._input.headers, options.headers),
      hooks: deepMerge({
        beforeRequest: [],
        beforeRetry: [],
        beforeError: [],
        afterResponse: []
      }, options.hooks),
      method: normalizeRequestMethod((_a = options.method) != null ? _a : this._input.method),
      prefixUrl: String(options.prefixUrl || ""),
      retry: normalizeRetryOptions(options.retry),
      throwHttpErrors: options.throwHttpErrors !== false,
      timeout: typeof options.timeout === "undefined" ? 1e4 : options.timeout,
      fetch: (_b = options.fetch) != null ? _b : globalThis.fetch.bind(globalThis)
    };
    if (typeof this._input !== "string" && !(this._input instanceof URL || this._input instanceof globalThis.Request)) {
      throw new TypeError("`input` must be a string, URL, or Request");
    }
    if (this._options.prefixUrl && typeof this._input === "string") {
      if (this._input.startsWith("/")) {
        throw new Error("`input` must not begin with a slash when using `prefixUrl`");
      }
      if (!this._options.prefixUrl.endsWith("/")) {
        this._options.prefixUrl += "/";
      }
      this._input = this._options.prefixUrl + this._input;
    }
    if (supportsAbortController) {
      this.abortController = new globalThis.AbortController();
      if (this._options.signal) {
        const originalSignal = this._options.signal;
        this._options.signal.addEventListener("abort", () => {
          this.abortController.abort(originalSignal.reason);
        });
      }
      this._options.signal = this.abortController.signal;
    }
    if (supportsRequestStreams) {
      this._options.duplex = "half";
    }
    this.request = new globalThis.Request(this._input, this._options);
    if (this._options.searchParams) {
      const textSearchParams = typeof this._options.searchParams === "string" ? this._options.searchParams.replace(/^\?/, "") : new URLSearchParams(this._options.searchParams).toString();
      const searchParams = "?" + textSearchParams;
      const url = this.request.url.replace(/(?:\?.*?)?(?=#|$)/, searchParams);
      if ((supportsFormData && this._options.body instanceof globalThis.FormData || this._options.body instanceof URLSearchParams) && !(this._options.headers && this._options.headers["content-type"])) {
        this.request.headers.delete("content-type");
      }
      this.request = new globalThis.Request(new globalThis.Request(url, {...this.request}), this._options);
    }
    if (this._options.json !== void 0) {
      this._options.body = JSON.stringify(this._options.json);
      this.request.headers.set("content-type", (_c = this._options.headers.get("content-type")) != null ? _c : "application/json");
      this.request = new globalThis.Request(this.request, {body: this._options.body});
    }
  }
  _calculateRetryDelay(error) {
    this._retryCount++;
    if (this._retryCount < this._options.retry.limit && !(error instanceof TimeoutError)) {
      if (error instanceof HTTPError) {
        if (!this._options.retry.statusCodes.includes(error.response.status)) {
          return 0;
        }
        const retryAfter = error.response.headers.get("Retry-After");
        if (retryAfter && this._options.retry.afterStatusCodes.includes(error.response.status)) {
          let after = Number(retryAfter);
          if (Number.isNaN(after)) {
            after = Date.parse(retryAfter) - Date.now();
          } else {
            after *= 1e3;
          }
          if (typeof this._options.retry.maxRetryAfter !== "undefined" && after > this._options.retry.maxRetryAfter) {
            return 0;
          }
          return after;
        }
        if (error.response.status === 413) {
          return 0;
        }
      }
      const BACKOFF_FACTOR = 0.3;
      return Math.min(this._options.retry.backoffLimit, BACKOFF_FACTOR * 2 ** (this._retryCount - 1) * 1e3);
    }
    return 0;
  }
  _decorateResponse(response) {
    if (this._options.parseJson) {
      response.json = async () => this._options.parseJson(await response.text());
    }
    return response;
  }
  async _retry(fn) {
    try {
      return await fn();
    } catch (error) {
      const ms = Math.min(this._calculateRetryDelay(error), maxSafeTimeout);
      if (ms !== 0 && this._retryCount > 0) {
        await delay(ms, {signal: this._options.signal});
        for (const hook of this._options.hooks.beforeRetry) {
          const hookResult = await hook({
            request: this.request,
            options: this._options,
            error,
            retryCount: this._retryCount
          });
          if (hookResult === stop) {
            return;
          }
        }
        return this._retry(fn);
      }
      throw error;
    }
  }
  async _fetch() {
    for (const hook of this._options.hooks.beforeRequest) {
      const result = await hook(this.request, this._options);
      if (result instanceof Request) {
        this.request = result;
        break;
      }
      if (result instanceof Response) {
        return result;
      }
    }
    if (this._options.timeout === false) {
      return this._options.fetch(this.request.clone());
    }
    return timeout(this.request.clone(), this.abortController, this._options);
  }
  _stream(response, onDownloadProgress) {
    const totalBytes = Number(response.headers.get("content-length")) || 0;
    let transferredBytes = 0;
    if (response.status === 204) {
      if (onDownloadProgress) {
        onDownloadProgress({percent: 1, totalBytes, transferredBytes}, new Uint8Array());
      }
      return new globalThis.Response(null, {
        status: response.status,
        statusText: response.statusText,
        headers: response.headers
      });
    }
    return new globalThis.Response(new globalThis.ReadableStream({
      async start(controller) {
        const reader = response.body.getReader();
        if (onDownloadProgress) {
          onDownloadProgress({percent: 0, transferredBytes: 0, totalBytes}, new Uint8Array());
        }
        async function read() {
          const {done, value} = await reader.read();
          if (done) {
            controller.close();
            return;
          }
          if (onDownloadProgress) {
            transferredBytes += value.byteLength;
            const percent = totalBytes === 0 ? 0 : transferredBytes / totalBytes;
            onDownloadProgress({percent, transferredBytes, totalBytes}, value);
          }
          controller.enqueue(value);
          await read();
        }
        await read();
      }
    }), {
      status: response.status,
      statusText: response.statusText,
      headers: response.headers
    });
  }
}
/*! MIT License © Sindre Sorhus */
const createInstance = (defaults) => {
  const ky2 = (input, options) => Ky.create(input, validateAndMerge(defaults, options));
  for (const method of requestMethods) {
    ky2[method] = (input, options) => Ky.create(input, validateAndMerge(defaults, options, {method}));
  }
  ky2.create = (newDefaults) => createInstance(validateAndMerge(newDefaults));
  ky2.extend = (newDefaults) => createInstance(validateAndMerge(defaults, newDefaults));
  ky2.stop = stop;
  return ky2;
};
const ky = createInstance();

const getText = async (url, options = {}) => {
  try {
    return await ky(url, options).text()
  } catch (error) {
    if (
      error &&
      error instanceof TypeError &&
      error.message === 'Failed to fetch'
    ) {
      throw new VError(
        error,
        `Failed to request text from "${url}". Make sure that the server is running and has CORS enabled`
      )
    }
    throw new VError(error, `Failed to request text from "${url}"`)
  }
};

// based on https://github.com/babel/babel/blob/6be6e04f396f03feace4431f709564a8d842163a/packages/babel-code-frame/src/index.ts (License MIT)

/**
 * RegExp to test for newlines in terminal.
 */

const NEWLINE = /\n/;

/**
 * Extract what lines should be marked and highlighted.
 */
const getMarkerLines = (loc, source, opts) => {
  const startLoc = {
    column: 0,
    line: -1,
    ...loc.start,
  };
  const endLoc = {
    ...startLoc,
    ...loc.end,
  };
  const { linesAbove = 2, linesBelow = 3 } = opts || {};
  const startLine = startLoc.line;
  const startColumn = startLoc.column;
  const endLine = endLoc.line;
  const endColumn = endLoc.column;

  let start = Math.max(startLine - (linesAbove + 1), 0);
  let end = Math.min(source.length, endLine + linesBelow);

  if (startLine === -1) {
    start = 0;
  }

  if (endLine === -1) {
    end = source.length;
  }

  const lineDiff = endLine - startLine;
  const markerLines = {};

  if (lineDiff) {
    for (let i = 0; i <= lineDiff; i++) {
      const lineNumber = i + startLine;

      if (!startColumn) {
        markerLines[lineNumber] = true;
      } else if (i === 0) {
        const sourceLength = source[lineNumber - 1].length;

        markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1];
      } else if (i === lineDiff) {
        markerLines[lineNumber] = [0, endColumn];
      } else {
        const sourceLength = source[lineNumber - i].length;

        markerLines[lineNumber] = [0, sourceLength];
      }
    }
  } else if (startColumn === endColumn) {
      if (startColumn) {
        markerLines[startLine] = [startColumn, 0];
      } else {
        markerLines[startLine] = true;
      }
    } else {
      markerLines[startLine] = [startColumn, endColumn - startColumn];
    }

  return { start, end, markerLines }
};

const create$1 = (rawLines, loc, opts = {}) => {
  const lines = rawLines.split(NEWLINE);
  const { start, end, markerLines } = getMarkerLines(loc, lines, opts);
  const hasColumns = loc.start && typeof loc.start.column === 'number';

  const numberMaxWidth = String(end).length;

  let frame = rawLines
    .split(NEWLINE, end)
    .slice(start, end)
    .map((line, index) => {
      const number = start + 1 + index;
      const paddedNumber = ` ${number}`.slice(-numberMaxWidth);
      const gutter = ` ${paddedNumber} |`;
      const hasMarker = markerLines[number];
      const lastMarkerLine = !markerLines[number + 1];
      if (hasMarker) {
        let markerLine = '';
        if (Array.isArray(hasMarker)) {
          const markerSpacing = line
            .slice(0, Math.max(hasMarker[0] - 1, 0))
            .replace(/[^\t]/g, ' ');
          const numberOfMarkers = hasMarker[1] || 1;

          markerLine = [
            '\n ',
            gutter.replace(/\d/g, ' '),
            ' ',
            markerSpacing,
            '^'.repeat(numberOfMarkers),
          ].join('');

          if (lastMarkerLine && opts.message) {
            markerLine += ' ' + opts.message;
          }
        }
        return [
          '>',
          gutter,
          line.length > 0 ? ` ${line}` : '',
          markerLine,
        ].join('')
      }
        return ` ${gutter}${line.length > 0 ? ` ${line}` : ''}`

    })
    .join('\n');

  if (opts.message && !hasColumns) {
    frame = `${' '.repeat(numberMaxWidth + 1)}${opts.message}\n${frame}`;
  }

  return frame
};

const getErrorMessage = (error) => {
  if (!error) {
    return `Error: ${error}`
  }
  let message = error.message;
  while (error.cause) {
    error = error.cause;
    message += `: ${error}`;
  }
  return message
};

const prepareErrorMessageWithCodeFrame = (error) => {
  if (!error) {
    return {
      message: error,
      stack: undefined,
      codeFrame: undefined,
      type: 'Error',
    }
  }
  const message = getErrorMessage(error);
  if (error.codeFrame) {
    return {
      message,
      stack: error.stack,
      codeFrame: error.codeFrame,
      type: error.constructor.name,
    }
  }
  return {
    message,
    stack: error.originalStack,
    codeFrame: error.originalCodeFrame,
    category: error.category,
    stderr: error.stderr,
  }
};

const RE_PATH_1 = /\((.*):(\d+):(\d+)\)$/;
const RE_PATH_2 = /at (.*):(\d+):(\d+)$/;

/**
 *
 * @param {readonly string[]} lines
 * @returns
 */
const getFile = (lines) => {
  for (const line of lines) {
    if (RE_PATH_1.test(line) || RE_PATH_2.test(line)) {
      return line
    }
  }
  return ''
};

const prepareErrorMessageWithoutCodeFrame = async (error) => {
  try {
    const lines = splitLines(error.stack);
    const file = getFile(lines);
    let match = file.match(RE_PATH_1);
    if (!match) {
      match = file.match(RE_PATH_2);
    }
    if (!match) {
      return error
    }
    const [_, path, line, column] = match;
    const text = await getText(path);
    const parsedLine = Number.parseInt(line);
    const parsedColumn = Number.parseInt(column);
    const codeFrame = create$1(text, {
      start: {
        line: parsedLine,
        column: parsedColumn,
      },
      end: {
        line: parsedLine,
        column: parsedColumn,
      },
    });
    const relevantStack = joinLines(lines.slice(1));
    const message = getErrorMessage(error);
    return {
      message,
      codeFrame,
      stack: relevantStack,
      type: error.constructor.name,
    }
  } catch (otherError) {
    console.warn('ErrorHandling Error');
    console.warn(otherError);
    return error
  }
};

const prepare = async (error) => {
  if (error && error.message && error.codeFrame) {
    return prepareErrorMessageWithCodeFrame(error)
  }
  if (error && error.stack) {
    return prepareErrorMessageWithoutCodeFrame(error)
  }
  return error
};

const getErrorResponse = async (message, error) => {
  if (error && error instanceof Error && error.message && error.message.startsWith('method not found')) {
    return {
      jsonrpc: Two,
      id: message.id,
      error: {
        code: MethodNotFound,
        message: error.message,
        data: error.stack,
      },
    }
  }
  const prettyError = await prepare(error);
  return {
    jsonrpc: Two,
    id: message.id,
    error: {
      code: Custom,
      message: prettyError.message,
      data: {
        stack: prettyError.stack,
        codeFrame: prettyError.codeFrame,
        type: prettyError.type,
      },
    },
  }
};

const getSuccessResponse = (message, result) => {
  return {
    jsonrpc: Two,
    id: message.id,
    result: result ?? null,
  }
};

const getResponse = async (message, execute) => {
  try {
    const result = await execute(message.method, ...message.params);
    return getSuccessResponse(message, result)
  } catch (error) {
    return getErrorResponse(message, error)
  }
};

const handleJsonRpcMessage = async (ipc, message, execute, resolve) => {
  if ('result' in message || 'error' in message) {
    resolve(message.id, message);
    return
  }
  const response = await getResponse(message, execute);
  ipc.send(response);
};

const handleIpc = (ipc, execute) => {
  object(ipc);
  fn(execute);
  const handleMessage = (message) => {
    return handleJsonRpcMessage(ipc, message, execute, resolve)
  };
  ipc.onmessage = handleMessage;
};

const MessagePort = 2;
const ModuleWorkerAndMessagePort = 8;

const Auto = () => {
  if (globalThis.acceptPort) {
    return MessagePort
  }
  if (globalThis.acceptReferencePort) {
    return 0
  }
  return ModuleWorkerAndMessagePort
};

const getModule = (method) => {
  switch (method) {
    case MessagePort:
      return Promise.resolve().then(function () { return IpcChildWithMessagePort; })
    case ModuleWorkerAndMessagePort:
      return Promise.resolve().then(function () { return IpcChildWithModuleWorkerAndMessagePort; })
    default:
      throw new Error('unexpected ipc type')
  }
};

const listen$4 = async ({ method }) => {
  const module = await getModule(method);
  const rawIpc = await module.listen();
  const ipc = module.wrap(rawIpc);
  return ipc
};

const create = (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 = '\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 recreateStack = (message, stack) => {
  if (message && !stack.includes(message)) {
    return message + NewLine + stack
  }
  return stack
};

const getErrorType = (error) => {
  if (error && error.type) {
    return error.type
  }
  if (error && error.data && error.data.type) {
    return error.data.type
  }
  return ''
};

const restoreJsonRpcError = (error) => {
  if (error && error instanceof Error) {
    return error
  }
  if (error && error.code && error.code === MethodNotFound) {
    const restoredError = new JsonRpcError(error.message);
    restoredError.stack = error.stack || error.data || '';
    return restoredError
  }
  if (error && error.message) {
    const type = getErrorType(error);
    const restoredError = constructError(error.message, type, error.name);
    const currentStack = joinLines(splitLines(new Error().stack).slice(1));
    if (error.data) {
      if (error.data.stack && type && error.message) {
        restoredError.stack = type + ': ' + error.message + NewLine + error.data.stack + NewLine + currentStack;
      } else if (error.data.stack) {
        restoredError.stack = recreateStack(error.message, error.data.stack) + NewLine + currentStack;
      }
      if (error.data.codeFrame) {
        // @ts-ignore
        restoredError.codeFrame = error.data.codeFrame;
      }
      if (error.data.code) {
        // @ts-ignore
        restoredError.code = error.data.code;
      }
    } else if (error.stack) {
      // @ts-ignore
      restoredError.stack = recreateStack(error.message, error.stack) + NewLine + currentStack;
    }
    return restoredError
  }
  if (typeof error === 'string') {
    return new Error(`JsonRpc Error: ${error}`)
  }
  console.log({ error });
  return new Error(`JsonRpc Error: Unknown 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 invoke = async (ipc, method, ...params) => {
  const { message, promise } = create(method, params);
  ipc.send(message);
  const responseMessage = await promise;
  const result = unwrapJsonRpcResult(responseMessage);
  return result
};

const listen$3 = async () => {
  registerCommands(commandMap);
  const ipc = await listen$4({ method: Auto() });
  handleIpc(ipc, execute);
  const rpc = {
    invoke(method, ...params) {
      return invoke(ipc, method, ...params)
    },
  };
  globalThis.rpc = rpc;
};

const main = async () => {
  await listen$3();
};

main();

const listen$2 = () => {
  const messageChannel = new MessageChannel();
  const { port1, port2 } = messageChannel;
  globalThis.acceptPort(port2);
  return port1
};

const wrap$2 = (port) => {
  return {
    port,
    send(message) {
      this.port.postMessage(message);
    },
    sendAndTransfer(message, transferables) {
      this.port.postMessage(message, transferables);
    },
    get onmessage() {
      return this.port.onmessage
    },
    set onmessage(listener) {
      this.port.onmessage = listener;
    },
  }
};

const IpcChildWithMessagePort = {
  __proto__: null,
  listen: listen$2,
  wrap: wrap$2
};

class IpcError extends Error {
  constructor(message) {
    super(message);
    this.name = 'IpcError';
  }
}

const listen$1 = async () => {
  if (typeof WorkerGlobalScope === 'undefined') {
    throw new IpcError('module is not in web worker scope')
  }
  globalThis.postMessage('ready');
  return globalThis
};

const getActualData$1 = (event) => {
  return event.data
};

const wrap$1 = (port) => {
  return {
    port,
    /**
     * @type {any}
     */
    wrappedListener: undefined,
    send(message) {
      this.port.postMessage(message);
    },
    sendAndTransfer(message, transferables) {
      this.port.postMessage(message, transferables);
    },
    get onmessage() {
      return this.wrappedListener
    },
    set onmessage(listener) {
      if (listener) {
        this.wrappedListener = (event) => {
          const actualData = getActualData$1(event);
          listener(actualData);
        };
      } else {
        this.wrappedListener = undefined;
      }
      this.port.onmessage = this.wrappedListener;
    },
  }
};

const waitForFirstMessage = async (port) => {
  const message = await new Promise((resolve) => {
    const cleanup = (value) => {
      port.onmessage = null;
      resolve(value);
    };
    const handleMessage = (message) => {
      cleanup(message);
    };
    port.onmessage = handleMessage;
  });
  return message
};

const listen = async () => {
  const parentIpcRaw = await listen$1();
  const parentIpc = wrap$1(parentIpcRaw);
  const firstMessage = await waitForFirstMessage(parentIpc);
  if (firstMessage.method !== 'initialize') {
    throw new IpcError('unexpected first message')
  }
  const type = firstMessage.params[0];
  if (type === 'message-port') {
    const port = firstMessage.params[1];
    return port
  }
  return globalThis
};

const getActualData = (event) => {
  return event.data
};

const wrap = (port) => {
  return {
    port,
    /**
     * @type {any}
     */
    wrappedListener: undefined,
    send(message) {
      this.port.postMessage(message);
    },
    sendAndTransfer(message, transferables) {
      this.port.postMessage(message, transferables);
    },
    get onmessage() {
      return this.wrappedListener
    },
    set onmessage(listener) {
      if (listener) {
        this.wrappedListener = (event) => {
          const actualData = getActualData(event);
          listener(actualData);
        };
      } else {
        this.wrappedListener = undefined;
      }
      this.port.onmessage = this.wrappedListener;
    },
  }
};

const IpcChildWithModuleWorkerAndMessagePort = {
  __proto__: null,
  listen,
  wrap
};
//# sourceMappingURL=extensionHostSubWorkerMain.js.map
