"use strict";
const events = require("./fetch-virtual-server-J6SUa9HS.cjs");
function escapeForScript(source) {
  return source.replace(/<\/script/gi, "<\\/script");
}
function buildElectronPreloadBootstrap(options = {}) {
  const preloadSource = escapeForScript(options.preloadSource ?? "");
  const tag = JSON.stringify(events.ELECTRON_IPC_TAG);
  const kind = JSON.stringify(events.ELECTRON_IPC_KIND);
  return `<script>
(function () {
  var TAG = ${tag};
  var KIND = ${kind};
  var invokeSeq = 0;
  var pendingInvokes = new Map();
  var channelListeners = new Map();

  function post(envelope) {
    envelope[TAG] = true;
    if (window.parent && window.parent !== window) {
      window.parent.postMessage(envelope, '*');
    }
  }

  window.addEventListener('message', function (event) {
    var data = event.data;
    if (!data || data[TAG] !== true) return;
    if (data.kind === KIND.invokeReply) {
      var pending = pendingInvokes.get(data.id);
      if (!pending) return;
      pendingInvokes.delete(data.id);
      if (data.ok) {
        pending.resolve(data.args ? data.args[0] : undefined);
      } else {
        var err = new Error(data.error ? data.error.message : 'IPC error');
        if (data.error && data.error.name) err.name = data.error.name;
        pending.reject(err);
      }
    } else if (data.kind === KIND.event) {
      var set = channelListeners.get(data.channel);
      if (!set) return;
      var ipcEvent = { senderId: 0, ports: [] };
      set.forEach(function (fn) {
        try { fn.apply(null, [ipcEvent].concat(data.args || [])); }
        catch (e) { console.error(e); }
      });
    } else if (data.kind === KIND.menuRole) {
      // Edit-role menu commands (Edit > Cut/Copy/Paste/...) applied best-effort.
      var roleCommands = {
        undo: 'undo', redo: 'redo', cut: 'cut', copy: 'copy', paste: 'paste',
        pasteAndMatchStyle: 'paste', 'delete': 'delete', selectAll: 'selectAll',
      };
      var command = data.args && roleCommands[data.args[0]];
      if (command) {
        try { document.execCommand(command); } catch (e) { /* unsupported */ }
      }
    }
  });

  var ipcRenderer = {
    invoke: function (channel) {
      var args = Array.prototype.slice.call(arguments, 1);
      var id = ++invokeSeq;
      return new Promise(function (resolve, reject) {
        pendingInvokes.set(id, { resolve: resolve, reject: reject });
        post({ kind: KIND.invoke, id: id, channel: channel, args: args });
      });
    },
    send: function (channel) {
      var args = Array.prototype.slice.call(arguments, 1);
      post({ kind: KIND.send, channel: channel, args: args });
    },
    sendSync: function () {
      console.warn('[electron] ipcRenderer.sendSync is not supported in almostnode');
      return undefined;
    },
    postMessage: function (channel) {
      var args = Array.prototype.slice.call(arguments, 1);
      post({ kind: KIND.send, channel: channel, args: args });
    },
    on: function (channel, listener) {
      var set = channelListeners.get(channel) || new Set();
      set.add(listener);
      channelListeners.set(channel, set);
      return ipcRenderer;
    },
    once: function (channel, listener) {
      var wrap = function () {
        ipcRenderer.removeListener(channel, wrap);
        return listener.apply(null, arguments);
      };
      return ipcRenderer.on(channel, wrap);
    },
    removeListener: function (channel, listener) {
      var set = channelListeners.get(channel);
      if (set) set.delete(listener);
      return ipcRenderer;
    },
    removeAllListeners: function (channel) {
      if (channel) channelListeners.delete(channel);
      else channelListeners.clear();
      return ipcRenderer;
    },
  };

  var contextBridge = {
    exposeInMainWorld: function (key, api) {
      try {
        Object.defineProperty(window, key, {
          value: api, enumerable: true, configurable: true, writable: false,
        });
      } catch (e) {
        window[key] = api;
      }
    },
    exposeInIsolatedWorld: function (_worldId, key, api) {
      contextBridge.exposeInMainWorld(key, api);
    },
  };

  var webFrame = {
    setZoomFactor: function () {}, getZoomFactor: function () { return 1; },
    setZoomLevel: function () {}, getZoomLevel: function () { return 0; },
    executeJavaScript: function () { return Promise.resolve(); },
    insertCSS: function (css) {
      try {
        var style = document.createElement('style');
        style.textContent = String(css);
        document.head.appendChild(style);
      } catch (e) { /* no document yet */ }
      return '';
    },
    insertText: function () { return Promise.resolve(); },
  };

  // Browsers can't expose a File's absolute filesystem path (removed from the
  // web platform), so this is best-effort — the name is the closest analog.
  var webUtils = {
    getPathForFile: function (file) {
      return file && typeof file.name === 'string' ? file.name : '';
    },
  };

  var electronRenderer = {
    ipcRenderer: ipcRenderer,
    contextBridge: contextBridge,
    webFrame: webFrame,
    webUtils: webUtils,
  };
  window.__almostElectronRenderer = electronRenderer;

  function preloadRequire(id) {
    if (id === 'electron') return electronRenderer;
    if (id === 'electron/renderer') return electronRenderer;
    throw new Error("[electron preload] Cannot require '" + id + "' in the renderer (contextIsolation MVP)");
  }

  try {
    (function (require, module, exports, process) {
${preloadSource}
    })(
      preloadRequire,
      { exports: {} },
      {},
      { platform: 'browser', env: {}, contextIsolated: true, versions: { electron: '31.0.0' } }
    );
  } catch (e) {
    console.error('[electron preload] preload script failed:', e);
  }

  post({ kind: KIND.rendererReady });
})();
<\/script>`;
}
const RENDERER_ROOT_CANDIDATES = [
  "src/renderer",
  "renderer",
  "src",
  "dist",
  "build",
  "out",
  "."
];
const PRELOAD_CANDIDATES = [
  "src/preload/index.ts",
  "src/preload/index.js",
  "src/preload/index.mjs",
  "src/preload/index.cjs",
  "src/preload.ts",
  "src/preload.js",
  "preload.ts",
  "preload.js",
  "preload.cjs",
  "electron/preload.ts",
  "electron/preload.js"
];
const MAIN_CANDIDATES = [
  "src/main/index.ts",
  "src/main/index.js",
  "src/main.ts",
  "src/main.js",
  "electron/main/index.ts",
  "electron/main/index.js",
  "electron/main.ts",
  "electron/main.js",
  "main.ts",
  "main.js"
];
function readJson(vfs, filePath) {
  try {
    return JSON.parse(vfs.readFileSync(filePath, "utf8"));
  } catch {
    return {};
  }
}
async function installAppDependencies(appDir, vfs, log) {
  const pkg = readJson(vfs, events.join(appDir, "package.json"));
  const deps = {
    ...pkg.dependencies ?? {},
    ...pkg.devDependencies ?? {}
  };
  if (Object.keys(deps).length === 0) return;
  if (vfs.existsSync(events.join(appDir, "node_modules"))) return;
  try {
    const { PackageManager } = await Promise.resolve().then(() => require("./index-CAJjEsYt.cjs")).then((n) => n.index);
    const pm = new PackageManager(vfs, { cwd: appDir });
    log(`[electron] installing ${Object.keys(deps).length} dependencies…
`);
    await pm.installFromPackageJson({
      onProgress: (message) => log(`[electron] ${message}
`)
    });
    log("[electron] dependencies installed\n");
  } catch (error) {
    log(
      `[electron] npm install failed (continuing): ${error instanceof Error ? error.message : String(error)}
`
    );
  }
}
function firstExisting(vfs, base, candidates) {
  for (const rel of candidates) {
    const abs = events.resolve(base, rel);
    if (vfs.existsSync(abs)) return abs;
  }
  return null;
}
function detectRendererRoot(vfs, appDir) {
  for (const rel of RENDERER_ROOT_CANDIDATES) {
    const dir = events.resolve(appDir, rel);
    if (vfs.existsSync(events.join(dir, "index.html"))) return dir;
  }
  return appDir;
}
function resolveMainEntry(vfs, appDir, pkg) {
  const mainRel = pkg.main || "main.js";
  const mainPath = events.resolve(appDir, mainRel);
  if (vfs.existsSync(mainPath)) return mainPath;
  return firstExisting(vfs, appDir, MAIN_CANDIDATES);
}
async function transpilePreload(source, filePath) {
  const isTs = /\.(ts|tsx|mts|cts)$/.test(filePath);
  const looksEsm = /\b(import|export)\b/.test(source);
  if (!isTs && !looksEsm) return source;
  const esbuild = globalThis.__esbuild;
  if (!esbuild) {
    console.warn(
      "[electron] esbuild unavailable — preload is ESM/TS and could not be transpiled"
    );
    return source;
  }
  const result = await esbuild.transform(source, {
    loader: isTs ? "ts" : "js",
    format: "cjs",
    target: "es2020"
  });
  return result.code;
}
function preloadImportsBareModule(source) {
  const re = /\b(?:import|require)\b[^\n]*?['"]([^'"\n]+)['"]/g;
  let match;
  while ((match = re.exec(source)) !== null) {
    const spec = match[1];
    if (spec.startsWith(".") || spec.startsWith("/")) continue;
    if (spec === "electron" || spec.startsWith("electron/")) continue;
    return true;
  }
  return false;
}
async function bundlePreload(source, filePath, vfs, log) {
  var _a, _b;
  if (!preloadImportsBareModule(source)) {
    return transpilePreload(source, filePath);
  }
  try {
    const esbuild = await Promise.resolve().then(() => require("./fetch-virtual-server-J6SUa9HS.cjs")).then((n) => n.esbuildShim);
    if (!esbuild.isInitialized()) await esbuild.initialize();
    const ext = events.extname(filePath).toLowerCase();
    const loader = ext === ".tsx" ? "tsx" : ext === ".jsx" ? "jsx" : /\.(ts|mts|cts)$/.test(ext) ? "ts" : "js";
    const result = await esbuild.build({
      stdin: { contents: source, resolveDir: events.dirname(filePath), loader },
      bundle: true,
      format: "cjs",
      platform: "browser",
      target: "es2020",
      external: ["electron", "electron/renderer"],
      write: false,
      vfs
    });
    const bundled = (_b = (_a = result.outputFiles) == null ? void 0 : _a[0]) == null ? void 0 : _b.text;
    if (bundled) {
      log("[electron] bundled preload with dependencies\n");
      return bundled;
    }
  } catch (error) {
    log(
      `[electron] preload bundling failed (${error instanceof Error ? error.message : String(error)}); using single-file transform
`
    );
  }
  return transpilePreload(source, filePath);
}
function createBridgeServerWrapper(devServer) {
  return {
    listening: true,
    address: () => ({ port: devServer.getPort(), address: "0.0.0.0", family: "IPv4" }),
    async handleRequest(method, url, headers, body) {
      const bodyBuffer = body ? typeof body === "string" ? Buffer.from(body) : body : void 0;
      return devServer.handleRequest(method, url, headers, bodyBuffer);
    }
  };
}
async function launchElectronApp(appDir, ctx) {
  const { vfs, runtime } = ctx;
  const log = ctx.onLog ?? (() => {
  });
  const pkg = readJson(vfs, events.join(appDir, "package.json"));
  const mainRel = pkg.main || "main.js";
  const mainPath = resolveMainEntry(vfs, appDir, pkg);
  if (!mainPath) {
    throw new Error(
      `electron: main entry not found: ${events.resolve(appDir, mainRel)}`
    );
  }
  if (mainPath !== events.resolve(appDir, mainRel)) {
    log(`[electron] main '${mainRel}' not built; using source entry ${mainPath}
`);
  }
  await installAppDependencies(appDir, vfs, log);
  const rendererRoot = detectRendererRoot(vfs, appDir);
  const preloadPath = firstExisting(vfs, appDir, PRELOAD_CANDIDATES);
  const mainIsTs = /\.(ts|tsx|mts|cts)$/.test(mainPath);
  const preloadIsTs = !!preloadPath && /\.(ts|tsx|mts|cts)$/.test(preloadPath);
  if (mainIsTs || preloadIsTs) {
    try {
      const { initTransformer } = await Promise.resolve().then(() => require("./transform-jXfghBBl.cjs"));
      await initTransformer();
    } catch (error) {
      log(
        `[electron] esbuild warm-up failed: ${error instanceof Error ? error.message : String(error)}
`
      );
    }
  }
  let preloadSource = "";
  if (preloadPath) {
    preloadSource = await bundlePreload(
      vfs.readFileSync(preloadPath, "utf8"),
      preloadPath,
      vfs,
      log
    );
    log(`[electron] preload: ${preloadPath}
`);
  }
  const [{ ViteDevServer }, { getServerBridge }] = await Promise.all([
    Promise.resolve().then(() => require("./vite-dev-server-CiHXpuZG.cjs")),
    Promise.resolve().then(() => require("./fetch-virtual-server-J6SUa9HS.cjs")).then((n) => n.serverBridge)
  ]);
  const bridge = getServerBridge();
  if (typeof navigator !== "undefined" && "serviceWorker" in navigator) {
    try {
      await bridge.initServiceWorker();
    } catch {
    }
  }
  const port = bridge.findFreePort(5273);
  const server = new ViteDevServer(vfs, {
    port,
    root: rendererRoot,
    publicDir: `${rendererRoot}/public`.replace(/\/+/g, "/"),
    spaFallback: true,
    deploymentBasePath: bridge.getBasePath(),
    injectHead: buildElectronPreloadBootstrap({ preloadSource })
  });
  server.start();
  bridge.registerServer(
    createBridgeServerWrapper(server),
    port,
    "0.0.0.0",
    { purpose: "auxiliary", framework: "vite", root: rendererRoot }
  );
  const rendererUrl = `${bridge.getServerUrl(port)}/`;
  log(`[electron] renderer dev server: ${rendererUrl} (root: ${rendererRoot})
`);
  const env = runtime.getProcess().env;
  env.VITE_DEV_SERVER_URL = rendererUrl;
  env.ELECTRON_RENDERER_URL = rendererUrl;
  env.__ALMOST_ELECTRON_DEV_URL = rendererUrl;
  env.__ALMOST_ELECTRON_RENDERER_ROOT = rendererRoot;
  const electronShim = runtime.getBuiltin("electron");
  const whenQuit = new Promise((resolve) => {
    var _a, _b;
    (_b = (_a = electronShim == null ? void 0 : electronShim.app) == null ? void 0 : _a.on) == null ? void 0 : _b.call(_a, "quit", (...args) => {
      resolve(typeof args[1] === "number" ? args[1] : 0);
    });
  });
  log(`[electron] main: ${mainPath}
`);
  await runtime.runFile(mainPath);
  return {
    rendererPort: port,
    rendererUrl,
    mainPath,
    whenQuit,
    close: () => {
      var _a;
      try {
        (_a = server.stop) == null ? void 0 : _a.call(server);
      } finally {
        bridge.unregisterServer(port);
      }
    }
  };
}
const electronApp = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  launchElectronApp,
  preloadImportsBareModule,
  resolveMainEntry
}, Symbol.toStringTag, { value: "Module" }));
exports.buildElectronPreloadBootstrap = buildElectronPreloadBootstrap;
exports.electronApp = electronApp;
exports.launchElectronApp = launchElectronApp;
//# sourceMappingURL=electron-app-BscWbxsQ.cjs.map
