'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var fs = require('node:fs/promises');
var path = require('node:path');
var node_url = require('node:url');
var require$$0 = require('fs');
var require$$1 = require('crypto');
var require$$2 = require('util');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);
var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1);
var require$$2__default = /*#__PURE__*/_interopDefaultLegacy(require$$2);

var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

function commonjsRequire(path) {
	throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
}

var __async$1 = (__this, __arguments, generator) => {
    return new Promise((resolve, reject) => {
        var fulfilled = value => {
            try {
                step(generator.next(value));
            } catch (e) {
                reject(e);
            }
        };
        var rejected = value => {
            try {
                step(generator.throw(value));
            } catch (e) {
                reject(e);
            }
        };
        var step = x => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
        step((generator = generator.apply(__this, __arguments)).next());
    });
};
(() => {
    if (typeof commonjsGlobal !== 'undefined') ; else if (typeof window !== 'undefined') {
        window.global = window;
    } else if (typeof self !== 'undefined') {
        self.global = self;
    } else {
        throw new Error('cannot export Go (neither global, window nor self is defined)');
    }
    if (!commonjsGlobal.require && typeof commonjsRequire !== 'undefined') {
        commonjsGlobal.require = commonjsRequire;
    }
    if (!commonjsGlobal.fs && commonjsGlobal.require) {
        commonjsGlobal.fs = require$$0__default["default"];
    }
    const enosys = () => {
        const err = new Error('not implemented');
        err.code = 'ENOSYS';
        return err;
    };
    if (!commonjsGlobal.fs) {
        let outputBuf = '';
        commonjsGlobal.fs = {
            constants: {
                O_WRONLY: -1,
                O_RDWR: -1,
                O_CREAT: -1,
                O_TRUNC: -1,
                O_APPEND: -1,
                O_EXCL: -1
            },
            writeSync(fd, buf) {
                outputBuf += decoder.decode(buf);
                const nl = outputBuf.lastIndexOf('\n');
                if (nl != -1) {
                    console.log(outputBuf.substr(0, nl));
                    outputBuf = outputBuf.substr(nl + 1);
                }
                return buf.length;
            },
            write(fd, buf, offset, length, position, callback) {
                if (offset !== 0 || length !== buf.length || position !== null) {
                    callback(enosys());
                    return;
                }
                const n = this.writeSync(fd, buf);
                callback(null, n);
            },
            chmod(path, mode, callback) {
                callback(enosys());
            },
            chown(path, uid, gid, callback) {
                callback(enosys());
            },
            close(fd, callback) {
                callback(enosys());
            },
            fchmod(fd, mode, callback) {
                callback(enosys());
            },
            fchown(fd, uid, gid, callback) {
                callback(enosys());
            },
            fstat(fd, callback) {
                callback(enosys());
            },
            fsync(fd, callback) {
                callback(null);
            },
            ftruncate(fd, length, callback) {
                callback(enosys());
            },
            lchown(path, uid, gid, callback) {
                callback(enosys());
            },
            link(path, link, callback) {
                callback(enosys());
            },
            lstat(path, callback) {
                callback(enosys());
            },
            mkdir(path, perm, callback) {
                callback(enosys());
            },
            open(path, flags, mode, callback) {
                callback(enosys());
            },
            read(fd, buffer, offset, length, position, callback) {
                callback(enosys());
            },
            readdir(path, callback) {
                callback(enosys());
            },
            readlink(path, callback) {
                callback(enosys());
            },
            rename(from, to, callback) {
                callback(enosys());
            },
            rmdir(path, callback) {
                callback(enosys());
            },
            stat(path, callback) {
                callback(enosys());
            },
            symlink(path, link, callback) {
                callback(enosys());
            },
            truncate(path, length, callback) {
                callback(enosys());
            },
            unlink(path, callback) {
                callback(enosys());
            },
            utimes(path, atime, mtime, callback) {
                callback(enosys());
            }
        };
    }
    if (!commonjsGlobal.process) {
        commonjsGlobal.process = {
            getuid() {
                return -1;
            },
            getgid() {
                return -1;
            },
            geteuid() {
                return -1;
            },
            getegid() {
                return -1;
            },
            getgroups() {
                throw enosys();
            },
            pid: -1,
            ppid: -1,
            umask() {
                throw enosys();
            },
            cwd() {
                throw enosys();
            },
            chdir() {
                throw enosys();
            }
        };
    }
    if (!commonjsGlobal.crypto) {
        const nodeCrypto = require$$1__default["default"];
        commonjsGlobal.crypto = {
            getRandomValues(b) {
                nodeCrypto.randomFillSync(b);
            }
        };
    }
    if (!commonjsGlobal.performance) {
        commonjsGlobal.performance = {
            now() {
                const [sec, nsec] = process.hrtime();
                return sec * 1000 + nsec / 1000000;
            }
        };
    }
    if (!commonjsGlobal.TextEncoder) {
        commonjsGlobal.TextEncoder = require$$2__default["default"].TextEncoder;
    }
    if (!commonjsGlobal.TextDecoder) {
        commonjsGlobal.TextDecoder = require$$2__default["default"].TextDecoder;
    }
    const encoder = new TextEncoder('utf-8');
    const decoder = new TextDecoder('utf-8');
    var logLine = [];
    commonjsGlobal.Go = class {
        constructor() {
            this._callbackTimeouts = /* @__PURE__ */
            new Map();
            this._nextCallbackTimeoutID = 1;
            const mem = () => {
                return new DataView(this._inst.exports.memory.buffer);
            };
            const setInt64 = (addr, v) => {
                mem().setUint32(addr + 0, v, true);
                mem().setUint32(addr + 4, Math.floor(v / 4294967296), true);
            };
            const loadValue = addr => {
                const f = mem().getFloat64(addr, true);
                if (f === 0) {
                    return void 0;
                }
                if (!isNaN(f)) {
                    return f;
                }
                const id = mem().getUint32(addr, true);
                return this._values[id];
            };
            const storeValue = (addr, v) => {
                const nanHead = 2146959360;
                if (typeof v === 'number') {
                    if (isNaN(v)) {
                        mem().setUint32(addr + 4, nanHead, true);
                        mem().setUint32(addr, 0, true);
                        return;
                    }
                    if (v === 0) {
                        mem().setUint32(addr + 4, nanHead, true);
                        mem().setUint32(addr, 1, true);
                        return;
                    }
                    mem().setFloat64(addr, v, true);
                    return;
                }
                switch (v) {
                case void 0:
                    mem().setFloat64(addr, 0, true);
                    return;
                case null:
                    mem().setUint32(addr + 4, nanHead, true);
                    mem().setUint32(addr, 2, true);
                    return;
                case true:
                    mem().setUint32(addr + 4, nanHead, true);
                    mem().setUint32(addr, 3, true);
                    return;
                case false:
                    mem().setUint32(addr + 4, nanHead, true);
                    mem().setUint32(addr, 4, true);
                    return;
                }
                let id = this._ids.get(v);
                if (id === void 0) {
                    id = this._idPool.pop();
                    if (id === void 0) {
                        id = this._values.length;
                    }
                    this._values[id] = v;
                    this._goRefCounts[id] = 0;
                    this._ids.set(v, id);
                }
                this._goRefCounts[id]++;
                let typeFlag = 1;
                switch (typeof v) {
                case 'string':
                    typeFlag = 2;
                    break;
                case 'symbol':
                    typeFlag = 3;
                    break;
                case 'function':
                    typeFlag = 4;
                    break;
                }
                mem().setUint32(addr + 4, nanHead | typeFlag, true);
                mem().setUint32(addr, id, true);
            };
            const loadSlice = (array, len, cap) => {
                return new Uint8Array(this._inst.exports.memory.buffer, array, len);
            };
            const loadSliceOfValues = (array, len, cap) => {
                const a = new Array(len);
                for (let i = 0; i < len; i++) {
                    a[i] = loadValue(array + i * 8);
                }
                return a;
            };
            const loadString = (ptr, len) => {
                return decoder.decode(new DataView(this._inst.exports.memory.buffer, ptr, len));
            };
            const timeOrigin = Date.now() - performance.now();
            this.importObject = {
                wasi_snapshot_preview1: {
                    fd_write: function (fd, iovs_ptr, iovs_len, nwritten_ptr) {
                        let nwritten = 0;
                        if (fd == 1) {
                            for (let iovs_i = 0; iovs_i < iovs_len; iovs_i++) {
                                let iov_ptr = iovs_ptr + iovs_i * 8;
                                let ptr = mem().getUint32(iov_ptr + 0, true);
                                let len = mem().getUint32(iov_ptr + 4, true);
                                nwritten += len;
                                for (let i = 0; i < len; i++) {
                                    let c = mem().getUint8(ptr + i);
                                    if (c == 13) ; else if (c == 10) {
                                        let line = decoder.decode(new Uint8Array(logLine));
                                        logLine = [];
                                        console.log(line);
                                    } else {
                                        logLine.push(c);
                                    }
                                }
                            }
                        } else {
                            console.error('invalid file descriptor:', fd);
                        }
                        mem().setUint32(nwritten_ptr, nwritten, true);
                        return 0;
                    },
                    fd_close: () => 0,
                    fd_fdstat_get: () => 0,
                    fd_seek: () => 0,
                    'proc_exit': code => {
                        if (commonjsGlobal.process) {
                            process.exit(code);
                        } else {
                            throw 'trying to exit with code ' + code;
                        }
                    },
                    random_get: (bufPtr, bufLen) => {
                        crypto.getRandomValues(loadSlice(bufPtr, bufLen));
                        return 0;
                    }
                },
                env: {
                    'runtime.ticks': () => {
                        return timeOrigin + performance.now();
                    },
                    'runtime.sleepTicks': timeout => {
                        setTimeout(this._inst.exports.go_scheduler, timeout);
                    },
                    'syscall/js.finalizeRef': sp => {
                        console.error('syscall/js.finalizeRef not implemented');
                    },
                    'syscall/js.stringVal': (ret_ptr, value_ptr, value_len) => {
                        const s = loadString(value_ptr, value_len);
                        storeValue(ret_ptr, s);
                    },
                    'syscall/js.valueGet': (retval, v_addr, p_ptr, p_len) => {
                        let prop = loadString(p_ptr, p_len);
                        let value = loadValue(v_addr);
                        let result = Reflect.get(value, prop);
                        storeValue(retval, result);
                    },
                    'syscall/js.valueSet': (v_addr, p_ptr, p_len, x_addr) => {
                        const v = loadValue(v_addr);
                        const p = loadString(p_ptr, p_len);
                        const x = loadValue(x_addr);
                        Reflect.set(v, p, x);
                    },
                    'syscall/js.valueDelete': (v_addr, p_ptr, p_len) => {
                        const v = loadValue(v_addr);
                        const p = loadString(p_ptr, p_len);
                        Reflect.deleteProperty(v, p);
                    },
                    'syscall/js.valueIndex': (ret_addr, v_addr, i) => {
                        storeValue(ret_addr, Reflect.get(loadValue(v_addr), i));
                    },
                    'syscall/js.valueSetIndex': (v_addr, i, x_addr) => {
                        Reflect.set(loadValue(v_addr), i, loadValue(x_addr));
                    },
                    'syscall/js.valueCall': (ret_addr, v_addr, m_ptr, m_len, args_ptr, args_len, args_cap) => {
                        const v = loadValue(v_addr);
                        const name = loadString(m_ptr, m_len);
                        const args = loadSliceOfValues(args_ptr, args_len);
                        try {
                            const m = Reflect.get(v, name);
                            storeValue(ret_addr, Reflect.apply(m, v, args));
                            mem().setUint8(ret_addr + 8, 1);
                        } catch (err) {
                            storeValue(ret_addr, err);
                            mem().setUint8(ret_addr + 8, 0);
                        }
                    },
                    'syscall/js.valueInvoke': (ret_addr, v_addr, args_ptr, args_len, args_cap) => {
                        try {
                            const v = loadValue(v_addr);
                            const args = loadSliceOfValues(args_ptr, args_len, args_cap);
                            storeValue(ret_addr, Reflect.apply(v, void 0, args));
                            mem().setUint8(ret_addr + 8, 1);
                        } catch (err) {
                            storeValue(ret_addr, err);
                            mem().setUint8(ret_addr + 8, 0);
                        }
                    },
                    'syscall/js.valueNew': (ret_addr, v_addr, args_ptr, args_len, args_cap) => {
                        const v = loadValue(v_addr);
                        const args = loadSliceOfValues(args_ptr, args_len);
                        try {
                            storeValue(ret_addr, Reflect.construct(v, args));
                            mem().setUint8(ret_addr + 8, 1);
                        } catch (err) {
                            storeValue(ret_addr, err);
                            mem().setUint8(ret_addr + 8, 0);
                        }
                    },
                    'syscall/js.valueLength': v_addr => {
                        return loadValue(v_addr).length;
                    },
                    'syscall/js.valuePrepareString': (ret_addr, v_addr) => {
                        const s = String(loadValue(v_addr));
                        const str = encoder.encode(s);
                        storeValue(ret_addr, str);
                        setInt64(ret_addr + 8, str.length);
                    },
                    'syscall/js.valueLoadString': (v_addr, slice_ptr, slice_len, slice_cap) => {
                        const str = loadValue(v_addr);
                        loadSlice(slice_ptr, slice_len).set(str);
                    },
                    'syscall/js.valueInstanceOf': (v_addr, t_addr) => {
                        return loadValue(v_addr) instanceof loadValue(t_addr);
                    },
                    'syscall/js.copyBytesToGo': (ret_addr, dest_addr, dest_len, dest_cap, source_addr) => {
                        let num_bytes_copied_addr = ret_addr;
                        let returned_status_addr = ret_addr + 4;
                        const dst = loadSlice(dest_addr, dest_len);
                        const src = loadValue(source_addr);
                        if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) {
                            mem().setUint8(returned_status_addr, 0);
                            return;
                        }
                        const toCopy = src.subarray(0, dst.length);
                        dst.set(toCopy);
                        setInt64(num_bytes_copied_addr, toCopy.length);
                        mem().setUint8(returned_status_addr, 1);
                    },
                    'syscall/js.copyBytesToJS': (ret_addr, dest_addr, source_addr, source_len, source_cap) => {
                        let num_bytes_copied_addr = ret_addr;
                        let returned_status_addr = ret_addr + 4;
                        const dst = loadValue(dest_addr);
                        const src = loadSlice(source_addr, source_len);
                        if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) {
                            mem().setUint8(returned_status_addr, 0);
                            return;
                        }
                        const toCopy = src.subarray(0, dst.length);
                        dst.set(toCopy);
                        setInt64(num_bytes_copied_addr, toCopy.length);
                        mem().setUint8(returned_status_addr, 1);
                    }
                }
            };
        }
        run(instance) {
            return __async$1(this, null, function* () {
                this._inst = instance;
                this._values = [
                    NaN,
                    0,
                    null,
                    true,
                    false,
                    commonjsGlobal,
                    this
                ];
                this._goRefCounts = [];
                this._ids = /* @__PURE__ */
                new Map();
                this._idPool = [];
                this.exited = false;
                new DataView(this._inst.exports.memory.buffer);
                while (true) {
                    const callbackPromise = new Promise(resolve => {
                        this._resolveCallbackPromise = () => {
                            if (this.exited) {
                                throw new Error('bad callback: Go program has already exited');
                            }
                            setTimeout(resolve, 0);
                        };
                    });
                    this._inst.exports._start();
                    if (this.exited) {
                        break;
                    }
                    yield callbackPromise;
                }
            });
        }
        _resume() {
            if (this.exited) {
                throw new Error('Go program has already exited');
            }
            this._inst.exports.resume();
            if (this.exited) {
                this._resolveExitPromise();
            }
        }
        _makeFuncWrapper(id) {
            const go = this;
            return function () {
                const event = {
                    id,
                    this: this,
                    args: arguments
                };
                go._pendingEvent = event;
                go._resume();
                return event.result;
            };
        }
    };
})();

var LangVariant = /* @__PURE__ */ ((LangVariant2) => {
  LangVariant2[LangVariant2["LangBash"] = 0] = "LangBash";
  LangVariant2[LangVariant2["LangPOSIX"] = 1] = "LangPOSIX";
  LangVariant2[LangVariant2["LangMirBSDKorn"] = 2] = "LangMirBSDKorn";
  LangVariant2[LangVariant2["LangBats"] = 3] = "LangBats";
  return LangVariant2;
})(LangVariant || {});

var __async = (__this, __arguments, generator) => {
  return new Promise((resolve, reject) => {
    var fulfilled = (value) => {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    };
    var rejected = (value) => {
      try {
        step(generator.throw(value));
      } catch (e) {
        reject(e);
      }
    };
    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
    step((generator = generator.apply(__this, __arguments)).next());
  });
};
class ParseError extends Error {
  constructor({ Filename, Incomplete, Text, Pos }) {
    super(Text);
    this.Filename = Filename;
    this.Incomplete = Incomplete;
    this.Text = Text;
    this.Pos = Pos;
  }
}
const getProcessor = (getWasmFile) => {
  let wasmFile;
  let wasmFilePromise;
  const encoder = new TextEncoder();
  const decoder = new TextDecoder();
  function processor(_0) {
    return __async(this, arguments, function* (textOrAst, {
      filepath,
      print = false,
      originalText,
      keepComments = true,
      stopAt = "",
      variant = LangVariant.LangBash,
      useTabs = false,
      tabWidth = 2,
      indent = useTabs ? 0 : tabWidth,
      binaryNextLine = true,
      switchCaseIndent = true,
      spaceRedirects = true,
      keepPadding = false,
      minify = false,
      functionNextLine = false
    } = {}) {
      if (!wasmFile) {
        if (!wasmFilePromise) {
          wasmFilePromise = Promise.resolve(getWasmFile());
        }
        wasmFile = yield wasmFilePromise;
      }
      if (typeof textOrAst !== "string" && !print) {
        print = true;
        if (originalText == null) {
          throw new TypeError("`originalText` is required for now, hope we will find better solution later");
        }
      }
      const go = new Go();
      const wasm = yield WebAssembly.instantiate(wasmFile, go.importObject);
      void go.run(wasm.instance);
      const { memory, wasmAlloc, wasmFree, process } = wasm.instance.exports;
      const filePath = encoder.encode(filepath);
      const text = encoder.encode(originalText || textOrAst);
      const uStopAt = encoder.encode(stopAt);
      const filePathPointer = wasmAlloc(filePath.byteLength);
      new Uint8Array(memory.buffer).set(filePath, filePathPointer);
      const textPointer = wasmAlloc(text.byteLength);
      new Uint8Array(memory.buffer).set(text, textPointer);
      const stopAtPointer = wasmAlloc(uStopAt.byteLength);
      new Uint8Array(memory.buffer).set(uStopAt, stopAtPointer);
      const resultPointer = process(filePathPointer, filePath.byteLength, filePath.byteLength, textPointer, text.byteLength, text.byteLength, print, keepComments, stopAtPointer, uStopAt.byteLength, uStopAt.byteLength, variant, indent, binaryNextLine, switchCaseIndent, spaceRedirects, keepPadding, minify, functionNextLine);
      wasmFree(filePathPointer);
      wasmFree(textPointer);
      wasmFree(stopAtPointer);
      const result = new Uint8Array(memory.buffer).subarray(resultPointer);
      const end = result.indexOf(0);
      const string = decoder.decode(result.subarray(0, end));
      if (!string.startsWith('{"') && !string.endsWith("}")) {
        throw new ParseError({
          Filename: filepath,
          Incomplete: true,
          Text: string
        });
      }
      const {
        file,
        text: processedText,
        parseError,
        message
      } = JSON.parse(string);
      if (parseError || message) {
        throw parseError == null ? new SyntaxError(message) : new ParseError(parseError);
      }
      return print ? processedText : file;
    });
  }
  return processor;
};

var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
const import_meta = {};
const _dirname = typeof __dirname === "undefined" ? path__default["default"].dirname(node_url.fileURLToPath(import_meta.url)) : __dirname;
const processor = getProcessor(() => fs__default["default"].readFile(path__default["default"].resolve(_dirname, "../main.wasm")));
const parse = (text, options) => processor(text, options);
function print(textOrAst, options) {
  if (typeof textOrAst === "string") {
    return processor(textOrAst, __spreadProps(__spreadValues({}, options), {
      print: true
    }));
  }
  return processor(textOrAst, options);
}

exports.LangVariant = LangVariant;
exports.ParseError = ParseError;
exports.getProcessor = getProcessor;
exports.parse = parse;
exports.print = print;
exports.processor = processor;
