lecodes-cli 2.5.0 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -64,7 +64,7 @@ var package_default;
64
64
  var init_package = __esm(() => {
65
65
  package_default = {
66
66
  name: "lecodes-cli",
67
- version: "2.5.0",
67
+ version: "2.5.1",
68
68
  dependencies: {
69
69
  "@letary/chisel": "^0.15.0",
70
70
  jimp: "^1.6.1",
@@ -89,9 +89,9 @@ var init_package = __esm(() => {
89
89
  },
90
90
  peerDependencies: {
91
91
  "lecodes-design": "^0.11.0",
92
- "lecodes-headless": "^2.5.0",
92
+ "lecodes-headless": "^2.5.1",
93
93
  "lecodes-3d-editor": "^0.9.0",
94
- "lecodes-assets": "^2.5.0",
94
+ "lecodes-assets": "^2.5.1",
95
95
  "heic-decode": "^2.1.0",
96
96
  "marcidb-embedded": "^0.15.0",
97
97
  sharp: "^0.35.2",
@@ -159,7 +159,7 @@ var init_package = __esm(() => {
159
159
  });
160
160
 
161
161
  // ../../sdk/src/version.ts
162
- var SDK_VERSION = "2.5.0";
162
+ var SDK_VERSION = "2.5.1";
163
163
 
164
164
  // src/cli/args.ts
165
165
  var isNegativeNumber = (s) => /^-(\d|\.\d)/.test(s), isValue = (s) => !s.startsWith("-") || isNegativeNumber(s), parseArgv = (argv, booleans = new Set) => {
@@ -209228,6 +209228,14 @@ var init_env3 = __esm(() => {
209228
209228
  env = makeEnv(currentEnv);
209229
209229
  });
209230
209230
 
209231
+ // ../../sdk/src/server/trustedCa.ts
209232
+ import { dirname as dirname19, join as join35 } from "node:path";
209233
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
209234
+ var TRUSTED_CA_FILE, trustedCaEnv = (env = process.env) => env.NODE_EXTRA_CA_CERTS ? {} : { NODE_EXTRA_CA_CERTS: TRUSTED_CA_FILE };
209235
+ var init_trustedCa = __esm(() => {
209236
+ TRUSTED_CA_FILE = join35(dirname19(fileURLToPath4(import.meta.url)), "certs", "russian-trusted-ca.pem");
209237
+ });
209238
+
209231
209239
  // ../../sdk/src/server/channelHub.ts
209232
209240
  var keyOf = (scope, ch, group) => `${scope}|${ch}|${JSON.stringify(group)}`, setFanout = (send) => {
209233
209241
  const sockets = new Map;
@@ -209747,7 +209755,7 @@ var init_host2 = __esm(() => {
209747
209755
  // ../../sdk/src/server/files/host.ts
209748
209756
  import { createReadStream } from "node:fs";
209749
209757
  import { mkdir, readFile as readFile3, readdir, rename, rm, stat, writeFile as writeFile3 } from "node:fs/promises";
209750
- import { basename as basename12, join as join35 } from "node:path";
209758
+ import { basename as basename12, join as join36 } from "node:path";
209751
209759
  import { Readable } from "node:stream";
209752
209760
  var UploadError, UUID, JOURNAL = "lecodes-files", MB, TMP_MAX_AGE_MS, MAX_IMAGE_PIXELS = 50000000, WEBP_QUALITY = 80, ascii = (b, at, text) => {
209753
209761
  for (let i = 0;i < text.length; i++)
@@ -209905,7 +209913,7 @@ var UploadError, UUID, JOURNAL = "lecodes-files", MB, TMP_MAX_AGE_MS, MAX_IMAGE_
209905
209913
  throw tooBig();
209906
209914
  blobs.push(part);
209907
209915
  }
209908
- const tmp = join35(dir, "tmp");
209916
+ const tmp = join36(dir, "tmp");
209909
209917
  await mkdir(tmp, { recursive: true });
209910
209918
  const uploads = [];
209911
209919
  try {
@@ -209920,7 +209928,7 @@ var UploadError, UUID, JOURNAL = "lecodes-files", MB, TMP_MAX_AGE_MS, MAX_IMAGE_
209920
209928
  size: bytes.length,
209921
209929
  ...size ?? {}
209922
209930
  };
209923
- await writeFile3(join35(tmp, upload.id), bytes);
209931
+ await writeFile3(join36(tmp, upload.id), bytes);
209924
209932
  uploads.push(upload);
209925
209933
  }
209926
209934
  } catch (e) {
@@ -209930,10 +209938,10 @@ var UploadError, UUID, JOURNAL = "lecodes-files", MB, TMP_MAX_AGE_MS, MAX_IMAGE_
209930
209938
  return { args, uploads };
209931
209939
  }, dropUploads = async (dir, uploads) => {
209932
209940
  for (const u of uploads)
209933
- await rm(join35(dir, "tmp", u.id), { force: true });
209941
+ await rm(join36(dir, "tmp", u.id), { force: true });
209934
209942
  }, fileResponse = async (dir, rest, req, headers = {}) => {
209935
209943
  const id = rest.split("/")[0];
209936
- const path = join35(dir, id);
209944
+ const path = join36(dir, id);
209937
209945
  const info = UUID.test(id) ? await stat(path).catch(() => null) : null;
209938
209946
  if (!info?.isFile())
209939
209947
  return new Response("Not found", { status: 404, headers });
@@ -209994,7 +210002,7 @@ var UploadError, UUID, JOURNAL = "lecodes-files", MB, TMP_MAX_AGE_MS, MAX_IMAGE_
209994
210002
  const codec = await (sharp ??= cfg.sharp?.() ?? Promise.resolve(null));
209995
210003
  if (!codec)
209996
210004
  throw new Error("files: a t.image() field needs sharp, and this host has none");
209997
- const path = join35(cfg.dir, id);
210005
+ const path = join36(cfg.dir, id);
209998
210006
  const bytes = new Uint8Array(await readFile3(path));
209999
210007
  const fit = await fitImage(codec, bytes, rule, sniffType(bytes) === "image/heic" ? await (heic ??= cfg.heic?.().catch(() => null) ?? Promise.resolve(null)) : null);
210000
210008
  if (!fit) {
@@ -210003,8 +210011,8 @@ var UploadError, UUID, JOURNAL = "lecodes-files", MB, TMP_MAX_AGE_MS, MAX_IMAGE_
210003
210011
  throw new UploadError(400, "the picture cannot be read");
210004
210012
  return { name: cleanName(names.get(id) ?? "", "image/gif"), type: "image/gif", size: bytes.length, ...size };
210005
210013
  }
210006
- await writeFile3(join35(cfg.dir, "tmp", id), fit.data);
210007
- await rename(join35(cfg.dir, "tmp", id), path);
210014
+ await writeFile3(join36(cfg.dir, "tmp", id), fit.data);
210015
+ await rename(join36(cfg.dir, "tmp", id), path);
210008
210016
  return { name: cleanName(names.get(id) ?? "", "image/webp"), type: "image/webp", size: fit.data.length, width: fit.width, height: fit.height };
210009
210017
  };
210010
210018
  const seam = {
@@ -210021,14 +210029,14 @@ var UploadError, UUID, JOURNAL = "lecodes-files", MB, TMP_MAX_AGE_MS, MAX_IMAGE_
210021
210029
  if (!entries.length)
210022
210030
  return;
210023
210031
  for (const entry of entries) {
210024
- await rm(join35(cfg.dir, entry.row.id), { force: true });
210032
+ await rm(join36(cfg.dir, entry.row.id), { force: true });
210025
210033
  after = entry.seq;
210026
210034
  }
210027
210035
  }
210028
210036
  });
210029
210037
  let ready = null;
210030
210038
  const start = () => ready ??= (async () => {
210031
- await mkdir(join35(cfg.dir, "tmp"), { recursive: true });
210039
+ await mkdir(join36(cfg.dir, "tmp"), { recursive: true });
210032
210040
  await exec({ action: "$journalOpen", journal: { name: JOURNAL, on: ["delete"] } });
210033
210041
  await exec({ action: "deleteMany", query: { $where: { ...ownerless, createdAt: { $lt: Date.now() - TMP_MAX_AGE_MS } } } });
210034
210042
  await settle();
@@ -210036,10 +210044,10 @@ var UploadError, UUID, JOURNAL = "lecodes-files", MB, TMP_MAX_AGE_MS, MAX_IMAGE_
210036
210044
  const known = new Set(rows.map((r) => r.id));
210037
210045
  for (const name of await readdir(cfg.dir)) {
210038
210046
  if (UUID.test(name) && !known.has(name))
210039
- await rm(join35(cfg.dir, name), { force: true });
210047
+ await rm(join36(cfg.dir, name), { force: true });
210040
210048
  }
210041
- for (const name of await readdir(join35(cfg.dir, "tmp"))) {
210042
- const path = join35(cfg.dir, "tmp", name);
210049
+ for (const name of await readdir(join36(cfg.dir, "tmp"))) {
210050
+ const path = join36(cfg.dir, "tmp", name);
210043
210051
  const info = await stat(path).catch(() => null);
210044
210052
  if (info && Date.now() - info.mtimeMs > TMP_MAX_AGE_MS)
210045
210053
  await rm(path, { force: true });
@@ -210058,7 +210066,7 @@ var UploadError, UUID, JOURNAL = "lecodes-files", MB, TMP_MAX_AGE_MS, MAX_IMAGE_
210058
210066
  for (const u of uploads)
210059
210067
  names.set(u.id, u.name);
210060
210068
  for (const u of uploads)
210061
- await rename(join35(cfg.dir, "tmp", u.id), join35(cfg.dir, u.id));
210069
+ await rename(join36(cfg.dir, "tmp", u.id), join36(cfg.dir, u.id));
210062
210070
  return uploads.map((u) => {
210063
210071
  const file = Object.freeze({ name: u.name, size: u.size, type: u.type });
210064
210072
  uploaded.set(file, u.id);
@@ -210078,7 +210086,7 @@ var UploadError, UUID, JOURNAL = "lecodes-files", MB, TMP_MAX_AGE_MS, MAX_IMAGE_
210078
210086
  await start();
210079
210087
  const id = crypto.randomUUID();
210080
210088
  const type = sniffType(bytes) ?? "application/octet-stream";
210081
- await writeFile3(join35(cfg.dir, "tmp", id), bytes);
210089
+ await writeFile3(join36(cfg.dir, "tmp", id), bytes);
210082
210090
  const size = imageSize(bytes, type);
210083
210091
  const [file] = await admit([{ id, name: basename12(path), type, size: bytes.length, ...size ?? {} }], rc);
210084
210092
  return uploaded.get(file);
@@ -210222,6 +210230,7 @@ var describeField = (f) => {
210222
210230
  var init_host4 = __esm(() => {
210223
210231
  init_runtime();
210224
210232
  init_env3();
210233
+ init_trustedCa();
210225
210234
  init_defineDb();
210226
210235
  init_host();
210227
210236
  init_host2();
@@ -227854,7 +227863,7 @@ var require_selfsigned = __commonJS(function(exports) {
227854
227863
  import { existsSync as existsSync62, mkdirSync as mkdirSync38, mkdtempSync as mkdtempSync9, renameSync as renameSync3, rmSync as rmSync20 } from "node:fs";
227855
227864
  import { readFile as readFile4 } from "node:fs/promises";
227856
227865
  import { tmpdir as tmpdir9 } from "node:os";
227857
- import { join as join67 } from "node:path";
227866
+ import { join as join68 } from "node:path";
227858
227867
  import { format } from "node:util";
227859
227868
  var post = (m) => {
227860
227869
  process.send?.(m);
@@ -227882,7 +227891,7 @@ var post = (m) => {
227882
227891
  if (e.kind !== "bad_request")
227883
227892
  throw e;
227884
227893
  const reason = e.message;
227885
- const probeDir = mkdtempSync9(join67(tmpdir9(), "lecodes-db-"));
227894
+ const probeDir = mkdtempSync9(join68(tmpdir9(), "lecodes-db-"));
227886
227895
  const probe = openDatabase(probeDir, { disableFsync: true });
227887
227896
  try {
227888
227897
  await probe.$sync(schema);
@@ -227950,7 +227959,7 @@ var post = (m) => {
227950
227959
  });
227951
227960
  files.install();
227952
227961
  try {
227953
- const seeded = await runSeed(server2, { files, read: async (path) => readFile4(join67(m.root, path)).catch(() => null) });
227962
+ const seeded = await runSeed(server2, { files, read: async (path) => readFile4(join68(m.root, path)).catch(() => null) });
227954
227963
  if (seeded.status === "seeded")
227955
227964
  notes.push(`seeded: ${Object.entries(seeded.rows).map(([name, n]) => `${name} ${n}`).join(", ")}`);
227956
227965
  } catch (e) {
@@ -228009,7 +228018,7 @@ var init_backendWorker = __esm(() => {
228009
228018
  init_package();
228010
228019
  init_cli();
228011
228020
  import { existsSync as existsSync63, realpathSync as realpathSync5 } from "node:fs";
228012
- import { delimiter as delimiter4, dirname as dirname32, join as join68 } from "node:path";
228021
+ import { delimiter as delimiter4, dirname as dirname33, join as join69 } from "node:path";
228013
228022
 
228014
228023
  // src/commands/app/index.ts
228015
228024
  init_manifest();
@@ -235570,27 +235579,28 @@ init_manifest();
235570
235579
  init_env2();
235571
235580
  init_shared();
235572
235581
  import { rmSync as rmSync10 } from "node:fs";
235573
- import { join as join37, relative as relative6 } from "node:path";
235582
+ import { join as join38, relative as relative6 } from "node:path";
235574
235583
 
235575
235584
  // src/dev/localBackend.ts
235585
+ init_host4();
235576
235586
  init_manifest();
235577
235587
  import { spawn as spawn6 } from "node:child_process";
235578
- import { basename as basename13, dirname as dirname19, join as join36 } from "node:path";
235579
- import { fileURLToPath as fileURLToPath4 } from "node:url";
235588
+ import { basename as basename13, dirname as dirname20, join as join37 } from "node:path";
235589
+ import { fileURLToPath as fileURLToPath5 } from "node:url";
235580
235590
  var BACKEND_WORKER_ARG = "__backend-worker";
235581
235591
  var selfCommand = () => {
235582
- const here = fileURLToPath4(import.meta.url);
235592
+ const here = fileURLToPath5(import.meta.url);
235583
235593
  if (/[\\/](\$bunfs|~BUN)[\\/]/.test(here))
235584
235594
  return [process.execPath];
235585
- const entry = /^localBackend\.[cm]?[jt]s$/.test(basename13(here)) ? join36(dirname19(here), "..", "index.ts") : here;
235595
+ const entry = /^localBackend\.[cm]?[jt]s$/.test(basename13(here)) ? join37(dirname20(here), "..", "index.ts") : here;
235586
235596
  return [process.execPath, ...process.execArgv, entry];
235587
235597
  };
235588
- var filesDirOf = (dbDir) => join36(dirname19(dbDir), basename13(dbDir).replace(/db$/, "") + "files");
235598
+ var filesDirOf = (dbDir) => join37(dirname20(dbDir), basename13(dbDir).replace(/db$/, "") + "files");
235589
235599
  var startLocalBackend = (options) => {
235590
235600
  const { log } = options;
235591
235601
  const invokeTimeoutMs = options.invokeTimeoutMs ?? 30000;
235592
235602
  const loadTimeoutMs = options.loadTimeoutMs ?? 15000;
235593
- const dbDir = options.dbDir ?? join36(options.root, LECODES_DIR, "db");
235603
+ const dbDir = options.dbDir ?? join37(options.root, LECODES_DIR, "db");
235594
235604
  const filesDir = options.filesDir ?? filesDirOf(dbDir);
235595
235605
  let live = null;
235596
235606
  let code = null;
@@ -235615,7 +235625,7 @@ var startLocalBackend = (options) => {
235615
235625
  };
235616
235626
  const start = (bundle, keys) => new Promise((resolve, reject) => {
235617
235627
  const [exe, ...args] = selfCommand();
235618
- const child = spawn6(exe, [...args, BACKEND_WORKER_ARG], { cwd: options.root, stdio: ["ignore", "inherit", "inherit", "ipc"] });
235628
+ const child = spawn6(exe, [...args, BACKEND_WORKER_ARG], { cwd: options.root, stdio: ["ignore", "inherit", "inherit", "ipc"], env: { ...process.env, ...trustedCaEnv() } });
235619
235629
  let exited;
235620
235630
  const l = { child, describe: null, pending: new Map, gone: new Promise((r) => {
235621
235631
  exited = r;
@@ -236023,7 +236033,7 @@ var bearerOf = (req) => /^Bearer\s+(.+)$/i.exec(req.headers.get("authorization")
236023
236033
  var BODY_LIMIT = 8 * 1024 * 1024;
236024
236034
  var createProjectBackend = (options) => {
236025
236035
  const { root, log } = options;
236026
- const dbDir = options.dbDir ?? join37(root, LECODES_DIR, "db");
236036
+ const dbDir = options.dbDir ?? join38(root, LECODES_DIR, "db");
236027
236037
  const filesDir = filesDirOf(dbDir);
236028
236038
  let backend = null;
236029
236039
  let running = null;
@@ -236147,7 +236157,7 @@ var stablePort = (root) => {
236147
236157
  };
236148
236158
  var runBackend = (options) => {
236149
236159
  const { root } = options;
236150
- const dbDir = join37(root, LECODES_DIR, options.test ? "test-db" : "db");
236160
+ const dbDir = join38(root, LECODES_DIR, options.test ? "test-db" : "db");
236151
236161
  if (options.test) {
236152
236162
  rmSync10(dbDir, { recursive: true, force: true });
236153
236163
  rmSync10(filesDirOf(dbDir), { recursive: true, force: true });
@@ -236299,14 +236309,14 @@ init_manifest();
236299
236309
  import { existsSync as existsSync38, mkdirSync as mkdirSync22, readFileSync as readFileSync33, writeFileSync as writeFileSync25 } from "node:fs";
236300
236310
  import { randomBytes as randomBytes5 } from "node:crypto";
236301
236311
  import { networkInterfaces } from "node:os";
236302
- import { basename as basename15, join as join43 } from "node:path";
236312
+ import { basename as basename15, join as join44 } from "node:path";
236303
236313
 
236304
236314
  // src/dev/devServer.ts
236305
236315
  init_env2();
236306
236316
  init_localFiles();
236307
236317
  import { createHash as createHash8 } from "node:crypto";
236308
236318
  import { createReadStream as createReadStream2, readFileSync as readFileSync31, statSync as statSync11 } from "node:fs";
236309
- import { join as join39 } from "node:path";
236319
+ import { join as join40 } from "node:path";
236310
236320
  import { Readable as Readable3 } from "node:stream";
236311
236321
  init_projectCompile();
236312
236322
  init_fonts();
@@ -236441,7 +236451,7 @@ init_paths();
236441
236451
  init_compile();
236442
236452
  init_cli();
236443
236453
  import { cpSync as cpSync5, existsSync as existsSync34, readFileSync as readFileSync30 } from "node:fs";
236444
- import { join as join38, sep as sep4 } from "node:path";
236454
+ import { join as join39, sep as sep4 } from "node:path";
236445
236455
  var halfModule = (half) => `plugins/${half.folder}/index.js`;
236446
236456
  var asCliError = (e) => new CliError(e instanceof Error ? e.message : String(e));
236447
236457
  var projectHalves = (root) => {
@@ -236451,17 +236461,17 @@ var projectHalves = (root) => {
236451
236461
  const folder = dir.split(sep4).pop();
236452
236462
  let web;
236453
236463
  try {
236454
- web = webHalfManifestOf(readFileSync30(join38(dir, MANIFEST_FILE), "utf8"), folder, id);
236464
+ web = webHalfManifestOf(readFileSync30(join39(dir, MANIFEST_FILE), "utf8"), folder, id);
236455
236465
  } catch (e) {
236456
236466
  throw asCliError(e);
236457
236467
  }
236458
236468
  const genId = web.implements ?? id;
236459
- if (!existsSync34(join38(dir, "web", `${genId}.gen.ts`))) {
236469
+ if (!existsSync34(join39(dir, "web", `${genId}.gen.ts`))) {
236460
236470
  throw new CliError(`Plugin "${id}": ${spec}/web/${genId}.gen.ts is not there — run \`lecodes plugin gen ${spec}\`.`);
236461
236471
  }
236462
236472
  if (halves.some((h) => h.folder === folder))
236463
236473
  throw new CliError(`Plugin "${id}": ${spec} is the half of another plugin already`);
236464
- halves.push({ id, folder, dir, manifest, entry: join38(dir, web.register), static: web.static });
236474
+ halves.push({ id, folder, dir, manifest, entry: join39(dir, web.register), static: web.static });
236465
236475
  }
236466
236476
  return halves;
236467
236477
  };
@@ -236470,7 +236480,7 @@ var buildHalf = (half, opts = {}) => bundleWebHalf({ id: half.id, dir: half.dir,
236470
236480
  });
236471
236481
  var copyStatic = (half, pluginsDir) => {
236472
236482
  if (half.static)
236473
- cpSync5(join38(half.dir, half.static), join38(pluginsDir, half.folder, half.static), { recursive: true });
236483
+ cpSync5(join39(half.dir, half.static), join39(pluginsDir, half.folder, half.static), { recursive: true });
236474
236484
  };
236475
236485
 
236476
236486
  // src/dev/devServer.ts
@@ -236592,7 +236602,7 @@ var startDevServer = async (options) => {
236592
236602
  const liteTable = () => {
236593
236603
  let plugins = {};
236594
236604
  try {
236595
- plugins = JSON.parse(readFileSync31(join39(lite, "plugins.json"), "utf8")).plugins ?? {};
236605
+ plugins = JSON.parse(readFileSync31(join40(lite, "plugins.json"), "utf8")).plugins ?? {};
236596
236606
  } catch {}
236597
236607
  const table = { ...plugins };
236598
236608
  for (const { half, hash } of halves) {
@@ -236656,7 +236666,7 @@ var startDevServer = async (options) => {
236656
236666
  const built = (dir, rel) => {
236657
236667
  if (rel.split("/").some((seg) => seg === ".." || seg === "" || seg === "."))
236658
236668
  return text(400, "text/plain", "Bad path");
236659
- const abs = join39(dir, ...rel.split("/"));
236669
+ const abs = join40(dir, ...rel.split("/"));
236660
236670
  try {
236661
236671
  if (!statSync11(abs).isFile())
236662
236672
  throw new Error("not a file");
@@ -236739,7 +236749,7 @@ var startDevServer = async (options) => {
236739
236749
  const name = route.slice("/shaders/".length);
236740
236750
  if (!isShaderArtifactName(name))
236741
236751
  return text(400, "text/plain", "Bad path");
236742
- const abs = join39(shadersCacheDir(root), name);
236752
+ const abs = join40(shadersCacheDir(root), name);
236743
236753
  try {
236744
236754
  if (!statSync11(abs).isFile())
236745
236755
  throw new Error("not a file");
@@ -236817,7 +236827,7 @@ init_distRoot();
236817
236827
  import { spawnSync as spawnSync8 } from "node:child_process";
236818
236828
  import { existsSync as existsSync35, readdirSync as readdirSync16, statSync as statSync12 } from "node:fs";
236819
236829
  import { createRequire as createRequire6 } from "node:module";
236820
- import { dirname as dirname20, join as join40 } from "node:path";
236830
+ import { dirname as dirname21, join as join41 } from "node:path";
236821
236831
  var PLAYER = {
236822
236832
  pkg: "lecodes-web-player",
236823
236833
  dist: "dist",
@@ -236849,12 +236859,12 @@ var resolveWebRunner = (log = () => {}) => {
236849
236859
  return player ? { player, page: resolve19(PAGE, log) } : null;
236850
236860
  };
236851
236861
  var resolve19 = (built, log) => {
236852
- const has = (dir) => existsSync35(join40(dir, "index.html")) && existsSync35(join40(dir, built.entry));
236862
+ const has = (dir) => existsSync35(join41(dir, "index.html")) && existsSync35(join41(dir, built.entry));
236853
236863
  const checkout = checkoutOf(built.pkg);
236854
236864
  if (checkout) {
236855
- const dist = join40(checkout, built.dist);
236856
- const repo = join40(checkout, "..", "..");
236857
- if (!has(dist) || newest(built.sources.map((s) => join40(repo, s))) > statSync12(join40(dist, built.entry)).mtimeMs) {
236865
+ const dist = join41(checkout, built.dist);
236866
+ const repo = join41(checkout, "..", "..");
236867
+ if (!has(dist) || newest(built.sources.map((s) => join41(repo, s))) > statSync12(join41(dist, built.entry)).mtimeMs) {
236858
236868
  log(`Building ${built.pkg} (its sources are newer than its build)…`);
236859
236869
  const done = spawnSync8("bunx", ["vite", "build", ...built.build], { cwd: checkout, stdio: "pipe", encoding: "utf8", shell: process.platform === "win32" });
236860
236870
  if (done.status !== 0)
@@ -236871,13 +236881,13 @@ ${step.stderr || step.stdout}`);
236871
236881
  if (has(dist))
236872
236882
  return dist;
236873
236883
  }
236874
- const vendored = join40(distRoot, "runtime", built.vendored);
236884
+ const vendored = join41(distRoot, "runtime", built.vendored);
236875
236885
  return has(vendored) ? vendored : null;
236876
236886
  };
236877
236887
  var checkoutOf = (pkg) => {
236878
236888
  try {
236879
- const dir = dirname20(createRequire6(import.meta.url).resolve(`${pkg}/package.json`));
236880
- return existsSync35(join40(dir, "vite.config.ts")) && existsSync35(join40(dir, "src")) ? dir : null;
236889
+ const dir = dirname21(createRequire6(import.meta.url).resolve(`${pkg}/package.json`));
236890
+ return existsSync35(join41(dir, "vite.config.ts")) && existsSync35(join41(dir, "src")) ? dir : null;
236881
236891
  } catch {
236882
236892
  return null;
236883
236893
  }
@@ -236897,7 +236907,7 @@ var newest = (paths) => {
236897
236907
  }
236898
236908
  for (const name of readdirSync16(path))
236899
236909
  if (name !== "node_modules" && name !== "ios" && name !== "android")
236900
- walk(join40(path, name));
236910
+ walk(join41(path, name));
236901
236911
  };
236902
236912
  for (const path of paths)
236903
236913
  walk(path);
@@ -236965,7 +236975,7 @@ init_browserAuth();
236965
236975
  // src/dev/androidDev.ts
236966
236976
  init_cli();
236967
236977
  import { existsSync as existsSync36, writeFileSync as writeFileSync24 } from "node:fs";
236968
- import { join as join41 } from "node:path";
236978
+ import { join as join42 } from "node:path";
236969
236979
  import { spawnSync as spawnSync9 } from "node:child_process";
236970
236980
  var DEFAULT_ANDROID_PACKAGE = "com.letary.lecodes";
236971
236981
  var adbCandidates = () => {
@@ -236976,12 +236986,12 @@ var adbCandidates = () => {
236976
236986
  const exe = process.platform === "win32" ? "adb.exe" : "adb";
236977
236987
  for (const home of [process.env.ANDROID_HOME, process.env.ANDROID_SDK_ROOT]) {
236978
236988
  if (home)
236979
- out.push(join41(home, "platform-tools", exe));
236989
+ out.push(join42(home, "platform-tools", exe));
236980
236990
  }
236981
236991
  if (process.platform === "win32" && process.env.LOCALAPPDATA)
236982
- out.push(join41(process.env.LOCALAPPDATA, "Android", "Sdk", "platform-tools", exe));
236992
+ out.push(join42(process.env.LOCALAPPDATA, "Android", "Sdk", "platform-tools", exe));
236983
236993
  if (process.env.HOME)
236984
- out.push(join41(process.env.HOME, "Android", "Sdk", "platform-tools", exe), join41(process.env.HOME, "Library", "Android", "sdk", "platform-tools", exe));
236994
+ out.push(join42(process.env.HOME, "Android", "Sdk", "platform-tools", exe), join42(process.env.HOME, "Library", "Android", "sdk", "platform-tools", exe));
236985
236995
  return out;
236986
236996
  };
236987
236997
  var run2 = (adb, args, input) => {
@@ -237087,7 +237097,7 @@ var androidCrashLines = (session) => {
237087
237097
  init_cli();
237088
237098
  import { existsSync as existsSync37, readdirSync as readdirSync17, readFileSync as readFileSync32, statSync as statSync13, unlinkSync } from "node:fs";
237089
237099
  import { homedir as homedir12 } from "node:os";
237090
- import { join as join42 } from "node:path";
237100
+ import { join as join43 } from "node:path";
237091
237101
  import { spawnSync as spawnSync10 } from "node:child_process";
237092
237102
  var DEFAULT_IOS_BUNDLE = "com.letary.lecodes";
237093
237103
  var run3 = (args) => {
@@ -237113,7 +237123,7 @@ var listSimulators = () => {
237113
237123
  }
237114
237124
  };
237115
237125
  var listDevices2 = () => {
237116
- const tmp = join42(process.env.TMPDIR ?? "/tmp", `lecodes-devicectl-${process.pid}.json`);
237126
+ const tmp = join43(process.env.TMPDIR ?? "/tmp", `lecodes-devicectl-${process.pid}.json`);
237117
237127
  const { ok } = run3(["devicectl", "list", "devices", "--json-output", tmp]);
237118
237128
  if (!ok || !existsSync37(tmp))
237119
237129
  return [];
@@ -237160,7 +237170,7 @@ var pickTarget = (udid) => {
237160
237170
  };
237161
237171
  var simulatorHasApp = (udid, bundleId) => run3(["simctl", "get_app_container", udid, bundleId]).ok;
237162
237172
  var deviceHasApp = (udid, bundleId) => {
237163
- const tmp = join42(process.env.TMPDIR ?? "/tmp", `lecodes-devicectl-apps-${process.pid}.json`);
237173
+ const tmp = join43(process.env.TMPDIR ?? "/tmp", `lecodes-devicectl-apps-${process.pid}.json`);
237164
237174
  const { ok } = run3(["devicectl", "device", "info", "apps", "--device", udid, "--json-output", tmp]);
237165
237175
  if (!ok || !existsSync37(tmp))
237166
237176
  return false;
@@ -237200,7 +237210,7 @@ var launchOnIos = (opts) => {
237200
237210
  throw new CliError(`Could not launch ${bundleId} on ${target.name}: ${start.out}`);
237201
237211
  pid = /:\s*(\d+)\s*$/.exec(start.out)?.[1] ?? null;
237202
237212
  } else {
237203
- const tmp = join42(process.env.TMPDIR ?? "/tmp", `lecodes-devicectl-launch-${process.pid}.json`);
237213
+ const tmp = join43(process.env.TMPDIR ?? "/tmp", `lecodes-devicectl-launch-${process.pid}.json`);
237204
237214
  const start = run3(["devicectl", "device", "process", "launch", "--device", target.udid, "--terminate-existing", "--json-output", tmp, bundleId, "--lecodes-url", url]);
237205
237215
  if (!start.ok)
237206
237216
  throw new CliError(`Could not launch ${bundleId} on ${target.name}: ${start.out}`);
@@ -237240,11 +237250,11 @@ var launchOnIos = (opts) => {
237240
237250
  crashLines: () => {
237241
237251
  if (target.kind !== "simulator")
237242
237252
  return [];
237243
- const dir = join42(homedir12(), "Library", "Logs", "DiagnosticReports");
237253
+ const dir = join43(homedir12(), "Library", "Logs", "DiagnosticReports");
237244
237254
  if (!existsSync37(dir))
237245
237255
  return [];
237246
237256
  const appName = bundleId.split(".").pop() ?? "";
237247
- return readdirSync17(dir).filter((f) => f.endsWith(".ips") && (f.startsWith("LeCodes") || appName && f.toLowerCase().startsWith(appName.toLowerCase()))).filter((f) => statSync13(join42(dir, f)).mtimeMs >= launchedAt).map((f) => join42(dir, f));
237257
+ return readdirSync17(dir).filter((f) => f.endsWith(".ips") && (f.startsWith("LeCodes") || appName && f.toLowerCase().startsWith(appName.toLowerCase()))).filter((f) => statSync13(join43(dir, f)).mtimeMs >= launchedAt).map((f) => join43(dir, f));
237248
237258
  }
237249
237259
  };
237250
237260
  };
@@ -237275,14 +237285,14 @@ var lanCandidates = () => {
237275
237285
  return out.sort((x, y) => x.rank - y.rank).map(({ address, iface }) => ({ address, iface }));
237276
237286
  };
237277
237287
  var loadDevToken = (root) => {
237278
- const path = join43(root, LECODES_DIR, "dev.json");
237288
+ const path = join44(root, LECODES_DIR, "dev.json");
237279
237289
  try {
237280
237290
  const token = JSON.parse(readFileSync33(path, "utf8")).token;
237281
237291
  if (token && /^[a-z0-9]{8,}$/.test(token))
237282
237292
  return token;
237283
237293
  } catch {}
237284
237294
  const token = randomBytes5(6).toString("hex");
237285
- mkdirSync22(join43(root, LECODES_DIR), { recursive: true });
237295
+ mkdirSync22(join44(root, LECODES_DIR), { recursive: true });
237286
237296
  writeFileSync25(path, JSON.stringify({ token }, null, 2) + `
237287
237297
  `);
237288
237298
  return token;
@@ -237394,7 +237404,7 @@ ${result.error}`);
237394
237404
  if (alternatives.length > 0) {
237395
237405
  note(`Device can't reach it? This machine also has ${alternatives.map((a) => `${a.address} (${a.iface})`).join(", ")} — retry with --host <ip>.`);
237396
237406
  }
237397
- if (existsSync38(join43(root, LECODES_DIR, "manifest.json")))
237407
+ if (existsSync38(join44(root, LECODES_DIR, "manifest.json")))
237398
237408
  note(`Token stored in ${LECODES_DIR}/dev.json (delete it to rotate the URL).`);
237399
237409
  log("");
237400
237410
  log(`Watching ${root} — save a file to hot-reload. Ctrl+C to stop.`);
@@ -237512,7 +237522,7 @@ init_cli();
237512
237522
  // src/commands/hub/create.ts
237513
237523
  init_cli();
237514
237524
  import { existsSync as existsSync40, realpathSync as realpathSync3 } from "node:fs";
237515
- import { join as join46, resolve as resolve20 } from "node:path";
237525
+ import { join as join47, resolve as resolve20 } from "node:path";
237516
237526
 
237517
237527
  // src/hub/api.ts
237518
237528
  init_cli();
@@ -237669,9 +237679,9 @@ var followDeployLog = async (base, token, ns, name, number, onText) => {
237669
237679
  init_cli();
237670
237680
  import { chmodSync as chmodSync2, mkdirSync as mkdirSync23, readFileSync as readFileSync34, writeFileSync as writeFileSync26 } from "node:fs";
237671
237681
  import { homedir as homedir13 } from "node:os";
237672
- import { join as join44 } from "node:path";
237682
+ import { join as join45 } from "node:path";
237673
237683
  var DEFAULT_HUB = "https://hub.le.codes";
237674
- var hubConfigPath = () => join44(homedir13(), ".lecodes", "hub.json");
237684
+ var hubConfigPath = () => join45(homedir13(), ".lecodes", "hub.json");
237675
237685
  var normalizeHubUrl = (url) => {
237676
237686
  const trimmed = url.trim().replace(/\/+$/, "");
237677
237687
  let parsed;
@@ -237700,7 +237710,7 @@ var requireHubConfig = () => {
237700
237710
  };
237701
237711
  var saveHubConfig = (config) => {
237702
237712
  const file = hubConfigPath();
237703
- mkdirSync23(join44(file, ".."), { recursive: true });
237713
+ mkdirSync23(join45(file, ".."), { recursive: true });
237704
237714
  writeFileSync26(file, JSON.stringify(config, null, 2) + `
237705
237715
  `, { mode: 384 });
237706
237716
  chmodSync2(file, 384);
@@ -237711,7 +237721,7 @@ var saveHubConfig = (config) => {
237711
237721
  init_cli();
237712
237722
  import { spawnSync as spawnSync11 } from "node:child_process";
237713
237723
  import { existsSync as existsSync39, realpathSync as realpathSync2 } from "node:fs";
237714
- import { basename as basename16, delimiter as delimiter2, join as join45 } from "node:path";
237724
+ import { basename as basename16, delimiter as delimiter2, join as join46 } from "node:path";
237715
237725
  var git2 = (args, cwd = process.cwd()) => {
237716
237726
  const r = spawnSync11("git", args, { cwd, encoding: "utf8", windowsHide: true });
237717
237727
  if (r.error)
@@ -237781,7 +237791,7 @@ var onPathAs = (target) => {
237781
237791
  return (process.env.PATH ?? "").split(delimiter2).some((d) => {
237782
237792
  if (!d)
237783
237793
  return false;
237784
- const cand = join45(d, exe);
237794
+ const cand = join46(d, exe);
237785
237795
  return existsSync39(cand) && real(cand) === want;
237786
237796
  });
237787
237797
  };
@@ -237867,7 +237877,7 @@ var create_default2 = defineCommand({
237867
237877
  examples: ["lecodes hub create demo", "lecodes hub create den/demo --private"],
237868
237878
  run: async ({ args, flags }) => {
237869
237879
  const cwd = process.cwd();
237870
- if (!existsSync40(join46(cwd, "app.json"))) {
237880
+ if (!existsSync40(join47(cwd, "app.json"))) {
237871
237881
  throw new CliError("No app.json in this folder — a hub project is a folder with app.json. Run `lecodes init` first (or cd into the project).");
237872
237882
  }
237873
237883
  if (!args[0])
@@ -238314,7 +238324,7 @@ init_manifest();
238314
238324
  init_types4();
238315
238325
  init_ignore();
238316
238326
  import { existsSync as existsSync41, mkdirSync as mkdirSync24, writeFileSync as writeFileSync27 } from "node:fs";
238317
- import { basename as basename17, dirname as dirname21, join as join47, resolve as resolve21 } from "node:path";
238327
+ import { basename as basename17, dirname as dirname22, join as join48, resolve as resolve21 } from "node:path";
238318
238328
  init_cli();
238319
238329
  var STARTER2 = `// Welcome to LeCodes — the whole SDK is available as globals, no imports needed.
238320
238330
  // Run it live on a device with \`lecodes dev\`, or bundle it with \`lecodes compile -o app.js\`.
@@ -238432,12 +238442,12 @@ var init3 = (dir, forDesktop) => {
238432
238442
  mkdirSync24(root, { recursive: true });
238433
238443
  let created = 0;
238434
238444
  const write = (rel, content) => {
238435
- const abs = join47(root, rel);
238445
+ const abs = join48(root, rel);
238436
238446
  if (existsSync41(abs)) {
238437
238447
  note(`kept ${rel}`);
238438
238448
  return;
238439
238449
  }
238440
- mkdirSync24(dirname21(abs), { recursive: true });
238450
+ mkdirSync24(dirname22(abs), { recursive: true });
238441
238451
  writeFileSync27(abs, content);
238442
238452
  log(`${c.green("created")} ${rel}`);
238443
238453
  created++;
@@ -238483,7 +238493,7 @@ init_cli();
238483
238493
  import { execFileSync as execFileSync7 } from "node:child_process";
238484
238494
  import { appendFileSync as appendFileSync3, chmodSync as chmodSync3, cpSync as cpSync6, existsSync as existsSync42, mkdirSync as mkdirSync25, readFileSync as readFileSync36, realpathSync as realpathSync4, rmSync as rmSync11, symlinkSync as symlinkSync2 } from "node:fs";
238485
238495
  import { homedir as homedir14 } from "node:os";
238486
- import { basename as basename18, delimiter as delimiter3, dirname as dirname22, join as join48, resolve as resolve22 } from "node:path";
238496
+ import { basename as basename18, delimiter as delimiter3, dirname as dirname23, join as join49, resolve as resolve22 } from "node:path";
238487
238497
  var isWin = process.platform === "win32";
238488
238498
  var HOME = homedir14();
238489
238499
  var safeRealpath = (p) => {
@@ -238510,9 +238520,9 @@ var copyBundle = (bundle, target, companions) => {
238510
238520
  if (safeRealpath(target) === safeRealpath(bundle))
238511
238521
  return;
238512
238522
  for (const f of companions) {
238513
- const dest = join48(target, f);
238523
+ const dest = join49(target, f);
238514
238524
  rmSync11(dest, { recursive: true, force: true });
238515
- cpSync6(join48(bundle, f), dest, { recursive: true });
238525
+ cpSync6(join49(bundle, f), dest, { recursive: true });
238516
238526
  }
238517
238527
  };
238518
238528
  var permError = (e, dir, system) => {
@@ -238525,10 +238535,10 @@ var permError = (e, dir, system) => {
238525
238535
  var shellRc = () => {
238526
238536
  const shell = basename18(process.env.SHELL ?? "");
238527
238537
  if (shell === "zsh")
238528
- return { file: join48(HOME, ".zshrc"), name: "~/.zshrc" };
238538
+ return { file: join49(HOME, ".zshrc"), name: "~/.zshrc" };
238529
238539
  if (shell === "bash")
238530
- return { file: join48(HOME, ".bashrc"), name: "~/.bashrc" };
238531
- return { file: join48(HOME, ".profile"), name: "~/.profile" };
238540
+ return { file: join49(HOME, ".bashrc"), name: "~/.bashrc" };
238541
+ return { file: join49(HOME, ".profile"), name: "~/.profile" };
238532
238542
  };
238533
238543
  var PATH_MARKER = "# Added by `lecodes install`";
238534
238544
  var appendPathToShellRc = (binDir) => {
@@ -238574,25 +238584,25 @@ var finishPathUnix = (modifyPath, binDir) => {
238574
238584
  };
238575
238585
  var installUnix = (opts, bundle, companions) => {
238576
238586
  const { system } = opts;
238577
- const libDir = resolve22(opts.dir ?? (system ? "/usr/local/lib/lecodes-cli" : join48(HOME, ".local", "lib", "lecodes-cli")));
238578
- const binDir = resolve22(opts.bin ?? (system ? "/usr/local/bin" : join48(HOME, ".local", "bin")));
238579
- const link = join48(binDir, "lecodes");
238587
+ const libDir = resolve22(opts.dir ?? (system ? "/usr/local/lib/lecodes-cli" : join49(HOME, ".local", "lib", "lecodes-cli")));
238588
+ const binDir = resolve22(opts.bin ?? (system ? "/usr/local/bin" : join49(HOME, ".local", "bin")));
238589
+ const link = join49(binDir, "lecodes");
238580
238590
  try {
238581
238591
  copyBundle(bundle, libDir, companions);
238582
- chmodSync3(join48(libDir, "lecodes"), 493);
238583
- chmodSync3(join48(libDir, "chisel"), 493);
238592
+ chmodSync3(join49(libDir, "lecodes"), 493);
238593
+ chmodSync3(join49(libDir, "chisel"), 493);
238584
238594
  } catch (e) {
238585
238595
  throw permError(e, libDir, system);
238586
238596
  }
238587
238597
  try {
238588
238598
  mkdirSync25(binDir, { recursive: true });
238589
238599
  rmSync11(link, { force: true });
238590
- symlinkSync2(join48(libDir, "lecodes"), link);
238600
+ symlinkSync2(join49(libDir, "lecodes"), link);
238591
238601
  } catch (e) {
238592
238602
  throw permError(e, binDir, system);
238593
238603
  }
238594
238604
  success(`Installed to ${c.bold(libDir)}`);
238595
- log(` ${c.dim(link + " → " + join48(libDir, "lecodes"))}`);
238605
+ log(` ${c.dim(link + " → " + join49(libDir, "lecodes"))}`);
238596
238606
  finishPathUnix(opts.modifyPath, binDir);
238597
238607
  };
238598
238608
  var addToUserPathWindows = (dir) => {
@@ -238605,7 +238615,7 @@ var addToUserPathWindows = (dir) => {
238605
238615
  }
238606
238616
  };
238607
238617
  var installWindows = (opts, bundle, companions) => {
238608
- const target = resolve22(opts.dir ?? join48(process.env.LOCALAPPDATA ?? join48(HOME, "AppData", "Local"), "Programs", "lecodes-cli"));
238618
+ const target = resolve22(opts.dir ?? join49(process.env.LOCALAPPDATA ?? join49(HOME, "AppData", "Local"), "Programs", "lecodes-cli"));
238609
238619
  try {
238610
238620
  copyBundle(bundle, target, companions);
238611
238621
  } catch (e) {
@@ -238642,13 +238652,13 @@ var install_default = defineCommand({
238642
238652
  },
238643
238653
  examples: ["lecodes install --modify-path", "sudo lecodes install --system"],
238644
238654
  run: ({ flags }) => {
238645
- const bundle = dirname22(process.execPath);
238655
+ const bundle = dirname23(process.execPath);
238646
238656
  const exeName = basename18(process.execPath);
238647
238657
  const chiselName = isWin ? "chisel.exe" : "chisel";
238648
- if (!existsSync42(join48(bundle, "runtime")) || !existsSync42(join48(bundle, chiselName))) {
238658
+ if (!existsSync42(join49(bundle, "runtime")) || !existsSync42(join49(bundle, chiselName))) {
238649
238659
  throw new CliError("`lecodes install` only works from the packaged release build (the archive containing lecodes + " + "chisel + runtime/). You appear to be running from source or an npm install — install globally " + "with your package manager there instead.");
238650
238660
  }
238651
- const companions = [exeName, chiselName, "runtime", "README.txt"].filter((f) => existsSync42(join48(bundle, f)));
238661
+ const companions = [exeName, chiselName, "runtime", "README.txt"].filter((f) => existsSync42(join49(bundle, f)));
238652
238662
  const opts = { modifyPath: flags["modify-path"], system: flags.system, dir: flags.dir, bin: flags.bin };
238653
238663
  if (isWin)
238654
238664
  return installWindows(opts, bundle, companions);
@@ -238659,7 +238669,7 @@ var install_default = defineCommand({
238659
238669
  // src/commands/lightmap.ts
238660
238670
  import { existsSync as existsSync43, mkdirSync as mkdirSync26, mkdtempSync as mkdtempSync4, readdirSync as readdirSync18, readFileSync as readFileSync37, rmSync as rmSync12, writeFileSync as writeFileSync28 } from "node:fs";
238661
238671
  import { tmpdir as tmpdir4 } from "node:os";
238662
- import { basename as basename19, dirname as dirname23, join as join49, relative as relative7, resolve as resolve23, sep as sep5 } from "node:path";
238672
+ import { basename as basename19, dirname as dirname24, join as join50, relative as relative7, resolve as resolve23, sep as sep5 } from "node:path";
238663
238673
  import { deflateSync } from "node:zlib";
238664
238674
  init_cli();
238665
238675
  init_shared();
@@ -238745,9 +238755,9 @@ var findBakes = (root) => {
238745
238755
  for (const e of readdirSync18(dir, { withFileTypes: true })) {
238746
238756
  if (e.isDirectory()) {
238747
238757
  if (!SKIP.has(e.name))
238748
- walk(join49(dir, e.name));
238758
+ walk(join50(dir, e.name));
238749
238759
  } else if (/\.bake$/i.test(e.name))
238750
- out.push(relative7(root, join49(dir, e.name)).replace(/\\/g, "/"));
238760
+ out.push(relative7(root, join50(dir, e.name)).replace(/\\/g, "/"));
238751
238761
  }
238752
238762
  };
238753
238763
  walk(root);
@@ -238893,13 +238903,13 @@ import ${JSON.stringify(importPath)}
238893
238903
  });
238894
238904
  const target = pickTarget2(bakes, flags.name, entryFile);
238895
238905
  const stem = stemOf(target.path);
238896
- const outDir = flags.out ? resolve23(root, flags.out) : dirname23(target.absPath);
238906
+ const outDir = flags.out ? resolve23(root, flags.out) : dirname24(target.absPath);
238897
238907
  mkdirSync26(outDir, { recursive: true });
238898
238908
  if (debugDir)
238899
238909
  mkdirSync26(debugDir, { recursive: true });
238900
- note(`Target: ${relative7(root, join49(outDir, `${stem}.bake`)).replace(/\\/g, "/")}${target.exists ? "" : " (the first bake: nothing there yet)"}${flags.out ? " (--out)" : ""}`);
238901
- const scratch = mkdtempSync4(join49(tmpdir4(), "lecodes-lightmap-"));
238902
- const outPng = join49(scratch, "frame.png");
238910
+ note(`Target: ${relative7(root, join50(outDir, `${stem}.bake`)).replace(/\\/g, "/")}${target.exists ? "" : " (the first bake: nothing there yet)"}${flags.out ? " (--out)" : ""}`);
238911
+ const scratch = mkdtempSync4(join50(tmpdir4(), "lecodes-lightmap-"));
238912
+ const outPng = join50(scratch, "frame.png");
238903
238913
  const bounce = cfg.bounceRays > 0 && cfg.bounces > 0 ? `, ${cfg.bounceRays} bounce paths of ${cfg.bounces}${cfg.patchSamples > 0 ? ` + ${cfg.patchSamples} patch samples` : ""}${cfg.denoise !== "none" ? `, denoised (${cfg.denoise})` : ", raw"}` : ", no bounce";
238904
238914
  note(`Baking up to ${cfg.pages} × ${cfg.size}² at ${(cfg.texel * 100).toFixed(1)} cm texels (${cfg.sunRays} sun + ${cfg.skyRays} sky + ${cfg.lightRays} lamp rays${bounce}) → ${relative7(root, outDir).split(sep5).join("/") || "."}/${stem}.*…`);
238905
238915
  let output = "";
@@ -238968,7 +238978,7 @@ import ${JSON.stringify(importPath)}
238968
238978
  return;
238969
238979
  }
238970
238980
  if (/\[lightmap\] done/.test(output)) {
238971
- const data = readBake(join49(outDir, `${stem}.bake`));
238981
+ const data = readBake(join50(outDir, `${stem}.bake`));
238972
238982
  const splitFiles = data.direct && data.indirect ? ` + ${data.direct.join(", ")} + ${data.indirect.join(", ")}` : "";
238973
238983
  const probeFiles = data.probes ? ` + ${data.probes.file} (${data.probes.count} probe(s) of ${data.probes.size}² at ${data.probes.spacing} m)` : "";
238974
238984
  const gridFile = data.volume ? ` + ${data.volume.file} (light grid ${data.volume.n.join(" x ")}, ${data.volume.valid} cell(s) in free space)` : "";
@@ -238976,8 +238986,8 @@ import ${JSON.stringify(importPath)}
238976
238986
  logErr(c.green(`✓ baked → ${relative7(root, outDir).replace(/\\/g, "/") || "."}/${stem}.bake + ${data.light.join(", ")} + ${data.aux.join(", ")}${splitFiles}${probeFiles}${gridFile}${uv1File}`));
238977
238987
  logErr(c.dim(flags.out ? ` written to --out: the level's bake() still reads ${target.path}` : ` the manifest names them: the next compile of ${entryFile} stages them (bake('…') in the scene reads it)`));
238978
238988
  if (debugDir)
238979
- logErr(c.dim(` debug layers: ${relative7(root, debugDir)} (lecodes lightmap inspect --bake ${relative7(root, join49(outDir, `${stem}.bake`)).replace(/\\/g, "/")} --debug-dir ${relative7(root, debugDir).replace(/\\/g, "/")})`));
238980
- stitchLevelCache(root, join49(outDir, `${stem}.static`), data);
238989
+ logErr(c.dim(` debug layers: ${relative7(root, debugDir)} (lecodes lightmap inspect --bake ${relative7(root, join50(outDir, `${stem}.bake`)).replace(/\\/g, "/")} --debug-dir ${relative7(root, debugDir).replace(/\\/g, "/")})`));
238990
+ stitchLevelCache(root, join50(outDir, `${stem}.static`), data);
238981
238991
  return;
238982
238992
  }
238983
238993
  if (/\[lightmap\] error: this host has no bake module/.test(output)) {
@@ -239070,7 +239080,7 @@ var diff = defineCommand({
239070
239080
  throw new CliError(`--layer: expected irradiance, bounce, sun, sky or lamps, got ${JSON.stringify(layer)}`);
239071
239081
  const n = a.instances.length;
239072
239082
  const texels = new Float64Array(n), sumMean = new Float64Array(n), sumVar = new Float64Array(n), off = new Float64Array(n);
239073
- const pageFile = (dir, stem, kind, page) => join49(dir, `${stem}-${kind}${page > 0 ? `_${page}` : ""}.pfm`);
239083
+ const pageFile = (dir, stem, kind, page) => join50(dir, `${stem}-${kind}${page > 0 ? `_${page}` : ""}.pfm`);
239074
239084
  for (let pg = 0;pg < a.pages; pg++) {
239075
239085
  const fa = pageFile(dirA, stemA, layer, pg), fb = pageFile(dirB, stemB, layer, pg), fi = pageFile(dirA, stemA, "ids", pg), fn = pageFile(dirA, stemA, "normal", pg);
239076
239086
  for (const f of [fa, fb, fi, fn])
@@ -239243,7 +239253,7 @@ var inspect = defineCommand({
239243
239253
  const [lo, hi] = flags["lux-range"].split(",").map(Number);
239244
239254
  const white = flags.white;
239245
239255
  const toneOf = (layer) => layer === "irradiance" || layer === "sun" || layer === "sky" || layer === "lamps" || layer === "bounce" || layer === "bounce-raw" || layer === "probes" ? white > 0 ? "linear" : "log" : layer === "direction" || layer === "normal" ? "normal" : layer === "position" ? "raw" : layer === "ids" ? "raw" : "raw";
239246
- const pageFile = (layer, page) => join49(dbg, `${stem}-${layer}${page > 0 ? `_${page}` : ""}.pfm`);
239256
+ const pageFile = (layer, page) => join50(dbg, `${stem}-${layer}${page > 0 ? `_${page}` : ""}.pfm`);
239247
239257
  const receivers = data.instances.filter((i) => i.receiver && i.rect);
239248
239258
  const re = flags.key ? new RegExp(flags.key) : null;
239249
239259
  const size = data.size;
@@ -239281,7 +239291,7 @@ var inspect = defineCommand({
239281
239291
  return [toneMap(L.data[i], tone, lo, hi, white), toneMap(L.data[i + 1], tone, lo, hi, white), toneMap(L.data[i + 2], tone, lo, hi, white)];
239282
239292
  };
239283
239293
  if (!re && layers.includes("probes")) {
239284
- const f = join49(dbg, `${stem}-probes.pfm`);
239294
+ const f = join50(dbg, `${stem}-probes.pfm`);
239285
239295
  if (!existsSync43(f))
239286
239296
  throw new CliError(`No ${relative7(root, f)} — bake with --probe-spacing > 0 and --debug-dir ${relative7(root, dbg) || "."} first.`);
239287
239297
  const L = readPfm(f);
@@ -239294,7 +239304,7 @@ var inspect = defineCommand({
239294
239304
  rgb[o + 1] = p[1];
239295
239305
  rgb[o + 2] = p[2];
239296
239306
  }
239297
- const file = join49(outDir, `${stem}-probes.png`);
239307
+ const file = join50(outDir, `${stem}-probes.png`);
239298
239308
  writePng(file, L.w, L.h, rgb);
239299
239309
  written++;
239300
239310
  logErr(c.dim(` ${relative7(root, file)} (${data.probes?.count ?? L.h / (L.w / 6)} probe(s), faces +X -X +Y -Y +Z -Z per row)`));
@@ -239334,7 +239344,7 @@ var inspect = defineCommand({
239334
239344
  rgb[o + 2] = 255;
239335
239345
  }
239336
239346
  }
239337
- const file = join49(outDir, `${stem}-${layer}${page > 0 ? `_${page}` : ""}.png`);
239347
+ const file = join50(outDir, `${stem}-${layer}${page > 0 ? `_${page}` : ""}.png`);
239338
239348
  writePng(file, size, size, rgb);
239339
239349
  written++;
239340
239350
  logErr(c.dim(` ${relative7(root, file)}`));
@@ -239370,7 +239380,7 @@ var inspect = defineCommand({
239370
239380
  }
239371
239381
  }
239372
239382
  const safe = r.key.replace(/[^A-Za-z0-9_.-]+/g, "_");
239373
- const file = join49(outDir, `${safe}-${layer}.png`);
239383
+ const file = join50(outDir, `${safe}-${layer}.png`);
239374
239384
  writePng(file, cw, chh, rgb);
239375
239385
  written++;
239376
239386
  }
@@ -239392,7 +239402,7 @@ var lightmap_default = defineCommand({
239392
239402
  init_cli();
239393
239403
  init_api();
239394
239404
  import { existsSync as existsSync45 } from "node:fs";
239395
- import { basename as basename21, join as join50, resolve as resolve25 } from "node:path";
239405
+ import { basename as basename21, join as join51, resolve as resolve25 } from "node:path";
239396
239406
  init_ignore();
239397
239407
  init_localFiles();
239398
239408
  init_manifest();
@@ -239723,7 +239733,7 @@ var link_default = defineCommand({
239723
239733
  const root = dirArg ? resolve25(dirArg) : process.cwd();
239724
239734
  if (!existsSync45(root))
239725
239735
  throw new CliError(`No such directory: ${root}`);
239726
- if (existsSync45(join50(root, LECODES_DIR, "manifest.json")) && !flags.force) {
239736
+ if (existsSync45(join51(root, LECODES_DIR, "manifest.json")) && !flags.force) {
239727
239737
  throw new CliError("This folder is already linked (.lecodes/manifest.json exists) — use `lecodes push`, or `lecodes link --force` to re-link it to another project.");
239728
239738
  }
239729
239739
  let enclosing = null;
@@ -239811,7 +239821,7 @@ var login_default2 = defineCommand({
239811
239821
  // src/commands/navmesh.ts
239812
239822
  import { existsSync as existsSync46, mkdirSync as mkdirSync27, mkdtempSync as mkdtempSync5, readdirSync as readdirSync19, readFileSync as readFileSync40, rmSync as rmSync13, statSync as statSync14, unlinkSync as unlinkSync2, writeFileSync as writeFileSync29 } from "node:fs";
239813
239823
  import { tmpdir as tmpdir5 } from "node:os";
239814
- import { basename as basename22, join as join51, relative as relative8, resolve as resolve26 } from "node:path";
239824
+ import { basename as basename22, join as join52, relative as relative8, resolve as resolve26 } from "node:path";
239815
239825
  init_cli();
239816
239826
  init_shared();
239817
239827
 
@@ -240606,7 +240616,7 @@ var range2 = (name, value, fallback, min, max) => {
240606
240616
  return n;
240607
240617
  };
240608
240618
  var guessNavmeshName = (root) => {
240609
- const dirs = [join51(root, "src"), root];
240619
+ const dirs = [join52(root, "src"), root];
240610
240620
  for (const dir of dirs) {
240611
240621
  if (!existsSync46(dir))
240612
240622
  continue;
@@ -240620,7 +240630,7 @@ var guessNavmeshName = (root) => {
240620
240630
  if (!f.endsWith(".scene.ts"))
240621
240631
  continue;
240622
240632
  try {
240623
- if (/\bnavmesh\s*:/.test(readFileSync40(join51(dir, f), "utf8")))
240633
+ if (/\bnavmesh\s*:/.test(readFileSync40(join52(dir, f), "utf8")))
240624
240634
  return f.slice(0, -".scene.ts".length);
240625
240635
  } catch {}
240626
240636
  }
@@ -240671,7 +240681,7 @@ var NAVMESH_FLAGS = {
240671
240681
  "keep-geometry": bool("keep the host's <name>.navgeo dump")
240672
240682
  };
240673
240683
  var finishNavmesh = async (root, outDir, name, output, flags) => {
240674
- const navmeshPath = join51(outDir, `${name}.navmesh`);
240684
+ const navmeshPath = join52(outDir, `${name}.navmesh`);
240675
240685
  const lines = output.split(/\r?\n/).filter((l) => l.includes("[navmesh]")).map((l) => l.slice(l.indexOf("[navmesh]")));
240676
240686
  let config = null;
240677
240687
  let triangles = 0;
@@ -240701,7 +240711,7 @@ var finishNavmesh = async (root, outDir, name, output, flags) => {
240701
240711
  }
240702
240712
  if (!config)
240703
240713
  throw new CliError("The host reported a dump but no `[navmesh] config` line — SDK/host mismatch?");
240704
- const geoPath = join51(outDir, `${name}.navgeo`);
240714
+ const geoPath = join52(outDir, `${name}.navgeo`);
240705
240715
  if (!existsSync46(geoPath))
240706
240716
  throw new CliError(`The host reported a dump but ${geoPath} is missing.`);
240707
240717
  const geo = readNgeo(new Uint8Array(readFileSync40(geoPath)));
@@ -240752,7 +240762,7 @@ var finishNavmesh = async (root, outDir, name, output, flags) => {
240752
240762
  }
240753
240763
  writeFileSync29(navmeshPath, result.data);
240754
240764
  if (flags.obj) {
240755
- const objPath = join51(outDir, `${name}.navmesh.obj`);
240765
+ const objPath = join52(outDir, `${name}.navmesh.obj`);
240756
240766
  writeObj(objPath, navMeshTriangles(mod, result.data));
240757
240767
  logErr(c.dim(` wrote ${relative8(root, objPath)} (the polygon mesh, for inspection)`));
240758
240768
  }
@@ -240797,7 +240807,7 @@ var bake2 = defineCommand({
240797
240807
  const height = win?.height || 720;
240798
240808
  const logs = flags.logs;
240799
240809
  mkdirSync27(outDir, { recursive: true });
240800
- const navmeshPath = join51(outDir, `${name}.navmesh`);
240810
+ const navmeshPath = join52(outDir, `${name}.navmesh`);
240801
240811
  if (!existsSync46(navmeshPath))
240802
240812
  writeFileSync29(navmeshPath, placeholderLnav());
240803
240813
  const importPath = "./" + entryFile.replace(/\\/g, "/").replace(/\.tsx?$/, "");
@@ -240813,8 +240823,8 @@ import ${JSON.stringify(importPath)}
240813
240823
  extraEntries: [{ path: entryPath, type: "text", text: entryText }],
240814
240824
  entryOverride: entryPath
240815
240825
  });
240816
- const scratch = mkdtempSync5(join51(tmpdir5(), "lecodes-navmesh-"));
240817
- const outPng = join51(scratch, "frame.png");
240826
+ const scratch = mkdtempSync5(join52(tmpdir5(), "lecodes-navmesh-"));
240827
+ const outPng = join52(scratch, "frame.png");
240818
240828
  note(`Dumping the level's static collision geometry through the desktop host → ${relative8(root, outDir) || "."}/${name}.navgeo…`);
240819
240829
  let output = "";
240820
240830
  try {
@@ -240853,7 +240863,7 @@ init_cli();
240853
240863
  init_cli();
240854
240864
  import { existsSync as existsSync47, mkdirSync as mkdirSync28, readFileSync as readFileSync41, readdirSync as readdirSync20, statSync as statSync15, writeFileSync as writeFileSync30 } from "node:fs";
240855
240865
  import { createRequire as createRequire7 } from "node:module";
240856
- import { basename as basename23, join as join52, relative as relative9, resolve as resolve27, sep as sep6 } from "node:path";
240866
+ import { basename as basename23, join as join53, relative as relative9, resolve as resolve27, sep as sep6 } from "node:path";
240857
240867
 
240858
240868
  // src/plugin/permissions.ts
240859
240869
  var PERMISSION_KINDS = ["camera", "microphone", "location", "speech"];
@@ -243725,24 +243735,24 @@ const wire = {
243725
243735
  var shown = (from, to) => relative9(from, to).split(sep6).join("/");
243726
243736
  var implementsOf = (dir) => {
243727
243737
  try {
243728
- const raw = JSON.parse(readFileSync41(join52(dir, MANIFEST_FILE), "utf8").replace(/^/, ""));
243738
+ const raw = JSON.parse(readFileSync41(join53(dir, MANIFEST_FILE), "utf8").replace(/^/, ""));
243729
243739
  return typeof raw.implements === "string" ? raw.implements : null;
243730
243740
  } catch {
243731
243741
  return null;
243732
243742
  }
243733
243743
  };
243734
- var isPluginDir = (dir) => existsSync47(join52(dir, CONTRACT_FILE)) || implementsOf(dir) !== null;
243744
+ var isPluginDir = (dir) => existsSync47(join53(dir, CONTRACT_FILE)) || implementsOf(dir) !== null;
243735
243745
  var findPlugins = (path) => {
243736
243746
  const root = resolve27(path);
243737
243747
  if (isPluginDir(root))
243738
243748
  return [{ id: basename23(root), dir: root }];
243739
- const holder = join52(root, "plugins");
243749
+ const holder = join53(root, "plugins");
243740
243750
  if (!existsSync47(holder))
243741
243751
  return [];
243742
- return readdirSync20(holder).sort().map((id) => ({ id, dir: join52(holder, id) })).filter((p) => statSync15(p.dir).isDirectory() && isPluginDir(p.dir));
243752
+ return readdirSync20(holder).sort().map((id) => ({ id, dir: join53(holder, id) })).filter((p) => statSync15(p.dir).isDirectory() && isPluginDir(p.dir));
243743
243753
  };
243744
243754
  var loadTypescript = (dir) => {
243745
- for (const from of [join52(dir, "package.json"), import.meta.url]) {
243755
+ for (const from of [join53(dir, "package.json"), import.meta.url]) {
243746
243756
  try {
243747
243757
  const mod = createRequire7(from)("typescript");
243748
243758
  const ts = mod?.createSourceFile ? mod : mod?.default;
@@ -243755,28 +243765,28 @@ var loadTypescript = (dir) => {
243755
243765
  var generatePlugin = (ts, plugin) => {
243756
243766
  const manifest = readManifestIfAny(plugin.dir, plugin.id);
243757
243767
  const implemented = manifest?.implements;
243758
- const file = implemented ? firstPartyContractFile(implemented) : join52(plugin.dir, CONTRACT_FILE);
243768
+ const file = implemented ? firstPartyContractFile(implemented) : join53(plugin.dir, CONTRACT_FILE);
243759
243769
  const contract = readContract(ts, file, implemented ? firstPartyContractText(file) : readFileSync41(file, "utf8"));
243760
243770
  checkPermissions(plugin, contract, manifest);
243761
243771
  const id = implemented ?? plugin.id;
243762
- const handWritten = existsSync47(join52(plugin.dir, "sdk", `${id}.ts`));
243772
+ const handWritten = existsSync47(join53(plugin.dir, "sdk", `${id}.ts`));
243763
243773
  const single = contract.channels.length === 1;
243764
243774
  const files = implemented ? [] : contract.channels.map((channel) => ({
243765
- file: join52(plugin.dir, "sdk", single ? `${id}.gen.ts` : `${id}.${channel.iface}.gen.ts`),
243775
+ file: join53(plugin.dir, "sdk", single ? `${id}.gen.ts` : `${id}.${channel.iface}.gen.ts`),
243766
243776
  text: emitSdk(contract, channel, { id, handWritten })
243767
243777
  }));
243768
- if (existsSync47(join52(plugin.dir, "ios"))) {
243778
+ if (existsSync47(join53(plugin.dir, "ios"))) {
243769
243779
  const name = single ? contract.channels[0].iface : contract.channels[0].iface + "Plugin";
243770
- files.push({ file: join52(plugin.dir, "ios", `${name}.gen.swift`), text: emitSwift(lower3(contract), { id }) });
243780
+ files.push({ file: join53(plugin.dir, "ios", `${name}.gen.swift`), text: emitSwift(lower3(contract), { id }) });
243771
243781
  }
243772
- if (existsSync47(join52(plugin.dir, "android"))) {
243782
+ if (existsSync47(join53(plugin.dir, "android"))) {
243773
243783
  const name = single ? contract.channels[0].iface : contract.channels[0].iface + "Plugin";
243774
- const pkg = kotlinPackage(join52(plugin.dir, "android"), manifest?.android?.register);
243775
- files.push({ file: join52(pkg.dir, `${name}.gen.kt`), text: emitKotlin(lower3(contract), { id, package: pkg.name }) });
243784
+ const pkg = kotlinPackage(join53(plugin.dir, "android"), manifest?.android?.register);
243785
+ files.push({ file: join53(pkg.dir, `${name}.gen.kt`), text: emitKotlin(lower3(contract), { id, package: pkg.name }) });
243776
243786
  }
243777
- if (existsSync47(join52(plugin.dir, "web"))) {
243778
- files.push({ file: join52(plugin.dir, "web", `${id}.gen.ts`), text: emitWeb(lower3(contract), { id }) });
243779
- const foreign = hostImports(join52(plugin.dir, "web"));
243787
+ if (existsSync47(join53(plugin.dir, "web"))) {
243788
+ files.push({ file: join53(plugin.dir, "web", `${id}.gen.ts`), text: emitWeb(lower3(contract), { id }) });
243789
+ const foreign = hostImports(join53(plugin.dir, "web"));
243780
243790
  if (foreign.length)
243781
243791
  throw new EmitError(`web/ imports the host — a web half depends on its generated file, the document it is handed and the browser:
243782
243792
  ${foreign.map((f) => ` ${f}`).join(`
@@ -243795,7 +243805,7 @@ var checkPermissions = (plugin, contract, manifest) => {
243795
243805
  kinds.push(k);
243796
243806
  if (kinds.length === 0)
243797
243807
  return;
243798
- const androidManifest = join52(plugin.dir, "android", "src", "main", "AndroidManifest.xml");
243808
+ const androidManifest = join53(plugin.dir, "android", "src", "main", "AndroidManifest.xml");
243799
243809
  const androidXml = manifest.android ? existsSync47(androidManifest) ? readFileSync41(androidManifest, "utf8") : "" : null;
243800
243810
  const missing = missingDeclarations(kinds, manifest.ios ? manifest.ios.infoPlist ?? {} : null, androidXml === null ? null : usesPermissions(androidXml), androidXml === null ? null : usesFeatures(androidXml));
243801
243811
  const problems = [];
@@ -243806,13 +243816,13 @@ var checkPermissions = (plugin, contract, manifest) => {
243806
243816
  if (missing.androidFeatures.length)
243807
243817
  problems.push(`android/src/main/AndroidManifest.xml: the contract's @permission implies <uses-feature android:name="…" android:required="false"/> for ${missing.androidFeatures.join(", ")} — without it Play requires the hardware`);
243808
243818
  if (problems.length)
243809
- throw new ManifestError(join52(plugin.dir, MANIFEST_FILE), problems);
243819
+ throw new ManifestError(join53(plugin.dir, MANIFEST_FILE), problems);
243810
243820
  };
243811
243821
  var hostImports = (web) => {
243812
243822
  const found = [];
243813
243823
  const walk = (dir) => {
243814
243824
  for (const entry of readdirSync20(dir).sort()) {
243815
- const path = join52(dir, entry);
243825
+ const path = join53(dir, entry);
243816
243826
  if (statSync15(path).isDirectory()) {
243817
243827
  if (entry !== "node_modules" && entry !== "dist")
243818
243828
  walk(path);
@@ -243824,7 +243834,7 @@ var hostImports = (web) => {
243824
243834
  `).forEach((line, i) => {
243825
243835
  const m = /(?:from\s+|import\s*\(\s*|import\s+)["'](lecodes-[^"']*)["']/.exec(line);
243826
243836
  if (m && !/^\s*\/\//.test(line))
243827
- found.push(`${shown(join52(web, ".."), path)}:${i + 1}: ${m[1]}`);
243837
+ found.push(`${shown(join53(web, ".."), path)}:${i + 1}: ${m[1]}`);
243828
243838
  });
243829
243839
  }
243830
243840
  };
@@ -243832,20 +243842,20 @@ var hostImports = (web) => {
243832
243842
  return found;
243833
243843
  };
243834
243844
  var kotlinPackage = (android, register) => {
243835
- const root = join52(android, "src", "main", "java");
243845
+ const root = join53(android, "src", "main", "java");
243836
243846
  if (register) {
243837
243847
  const name = register.split(".").slice(0, -1).join(".");
243838
- const dir = join52(root, ...name.split("."));
243848
+ const dir = join53(root, ...name.split("."));
243839
243849
  if (name && existsSync47(dir))
243840
243850
  return { dir, name };
243841
243851
  }
243842
243852
  let dir = root;
243843
243853
  while (existsSync47(dir)) {
243844
243854
  const entries = readdirSync20(dir).filter((e) => !e.startsWith("."));
243845
- const dirs = entries.filter((e) => statSync15(join52(dir, e)).isDirectory());
243855
+ const dirs = entries.filter((e) => statSync15(join53(dir, e)).isDirectory());
243846
243856
  if (dirs.length !== 1 || entries.length !== 1)
243847
243857
  break;
243848
- dir = join52(dir, dirs[0]);
243858
+ dir = join53(dir, dirs[0]);
243849
243859
  }
243850
243860
  if (dir === root) {
243851
243861
  throw new EmitError(`android/ has no package yet — make the folder of the plugin's Kotlin package (android/src/main/java/com/example/plugin), the generated file is written into it`);
@@ -243853,7 +243863,7 @@ var kotlinPackage = (android, register) => {
243853
243863
  return { dir, name: relative9(root, dir).split(/[\\/]/).join(".") };
243854
243864
  };
243855
243865
  var repoSdkPath = (root) => {
243856
- const file = join52(root, "package.json");
243866
+ const file = join53(root, "package.json");
243857
243867
  if (!existsSync47(file))
243858
243868
  return DEFAULT_SDK_PATH;
243859
243869
  try {
@@ -243886,7 +243896,7 @@ var generate = (path, opts = {}) => {
243886
243896
  entry.stale.push(name);
243887
243897
  return;
243888
243898
  }
243889
- mkdirSync28(join52(f.file, ".."), { recursive: true });
243899
+ mkdirSync28(join53(f.file, ".."), { recursive: true });
243890
243900
  writeFileSync30(f.file, f.text);
243891
243901
  entry.written.push(name);
243892
243902
  };
@@ -243905,7 +243915,7 @@ var generate = (path, opts = {}) => {
243905
243915
  report.failures.push(e.problems.map((p) => `${shown(root, e.file) || e.file}:${p.line}: ${p.message}`).join(`
243906
243916
  `));
243907
243917
  else if (e instanceof EmitError)
243908
- report.failures.push(`${shown(root, join52(plugin.dir, CONTRACT_FILE))}: ${e.message}`);
243918
+ report.failures.push(`${shown(root, join53(plugin.dir, CONTRACT_FILE))}: ${e.message}`);
243909
243919
  else if (e instanceof ManifestError)
243910
243920
  report.failures.push(`${shown(root, e.file) || e.file}:
243911
243921
  ${e.problems.map((p) => ` ${p}`).join(`
@@ -243917,7 +243927,7 @@ ${e.problems.map((p) => ` ${p}`).join(`
243917
243927
  const isRepo = !(plugins.length === 1 && plugins[0].dir === root);
243918
243928
  if (isRepo && report.failures.length === 0 && manifests.some((m) => m.manifest.ios !== null)) {
243919
243929
  try {
243920
- place({ file: join52(root, PACKAGE_FILE), text: emitPackageSwift(manifests, repoSdkPath(root)) }, report.repo);
243930
+ place({ file: join53(root, PACKAGE_FILE), text: emitPackageSwift(manifests, repoSdkPath(root)) }, report.repo);
243921
243931
  } catch (e) {
243922
243932
  if (e instanceof PackageError)
243923
243933
  report.failures.push(`${PACKAGE_FILE}: ${e.message}`);
@@ -244224,7 +244234,7 @@ init_api();
244224
244234
  init_localFiles();
244225
244235
  init_manifest();
244226
244236
  import { existsSync as existsSync48, mkdirSync as mkdirSync29, rmSync as rmSync14, writeFileSync as writeFileSync31 } from "node:fs";
244227
- import { dirname as dirname24, join as join53 } from "node:path";
244237
+ import { dirname as dirname25, join as join54 } from "node:path";
244228
244238
  init_paths();
244229
244239
  init_types4();
244230
244240
  init_shared();
@@ -244253,7 +244263,7 @@ var pull_default = defineCommand({
244253
244263
  for (const path of Object.keys(manifest.files)) {
244254
244264
  if (remotePaths.has(path))
244255
244265
  continue;
244256
- const abs = join53(root, ...path.replace(/^\//, "").split("/"));
244266
+ const abs = join54(root, ...path.replace(/^\//, "").split("/"));
244257
244267
  if (existsSync48(abs))
244258
244268
  rmSync14(abs);
244259
244269
  }
@@ -244292,8 +244302,8 @@ var pullPaths = async (root, manifest, project, paths, apiUrl, token) => {
244292
244302
  const files = { ...manifest.files };
244293
244303
  for (const asset of targets) {
244294
244304
  const key = pathById.get(asset.id);
244295
- const abs = join53(root, ...key.replace(/^\//, "").split("/"));
244296
- mkdirSync29(dirname24(abs), { recursive: true });
244305
+ const abs = join54(root, ...key.replace(/^\//, "").split("/"));
244306
+ mkdirSync29(dirname25(abs), { recursive: true });
244297
244307
  let sha;
244298
244308
  if (asset.type === "file") {
244299
244309
  if (!asset.file?.src)
@@ -244321,7 +244331,7 @@ init_api();
244321
244331
  init_env2();
244322
244332
  init_shared();
244323
244333
  import { readdirSync as readdirSync21, readFileSync as readFileSync42, statSync as statSync16 } from "node:fs";
244324
- import { join as join54, relative as relative10 } from "node:path";
244334
+ import { join as join55, relative as relative10 } from "node:path";
244325
244335
  var SKIP_DIRS3 = new Set(["node_modules", ".lecodes", ".git", "dist", "design"]);
244326
244336
  var readsOf = (root) => {
244327
244337
  const out = new Map;
@@ -244329,7 +244339,7 @@ var readsOf = (root) => {
244329
244339
  for (const entry of readdirSync21(dir)) {
244330
244340
  if (entry.startsWith("_") || entry.startsWith(".") || SKIP_DIRS3.has(entry))
244331
244341
  continue;
244332
- const path = join54(dir, entry);
244342
+ const path = join55(dir, entry);
244333
244343
  let isDir = false;
244334
244344
  try {
244335
244345
  isDir = statSync16(path).isDirectory();
@@ -244407,7 +244417,7 @@ var set = defineCommand({
244407
244417
  if (flags["from-env"]) {
244408
244418
  const local = readAppEnv(root);
244409
244419
  if (!(name in local))
244410
- throw new CliError(`${name} is not in ${relative10(process.cwd(), join54(root, ".env")) || ".env"} — add a line \`${name}=value\` first`);
244420
+ throw new CliError(`${name} is not in ${relative10(process.cwd(), join55(root, ".env")) || ".env"} — add a line \`${name}=value\` first`);
244411
244421
  value = local[name];
244412
244422
  }
244413
244423
  if (value === undefined) {
@@ -244473,7 +244483,7 @@ var secrets_default = defineCommand({
244473
244483
 
244474
244484
  // src/commands/render.ts
244475
244485
  import { mkdirSync as mkdirSync31, readFileSync as readFileSync44, writeFileSync as writeFileSync33 } from "node:fs";
244476
- import { dirname as dirname25, resolve as resolve31 } from "node:path";
244486
+ import { dirname as dirname26, resolve as resolve31 } from "node:path";
244477
244487
 
244478
244488
  // src/compile/headlessBundle.ts
244479
244489
  init_env2();
@@ -244563,7 +244573,7 @@ init_designMeta();
244563
244573
  init_cli();
244564
244574
  init_paths();
244565
244575
  import { existsSync as existsSync49, readFileSync as readFileSync43, statSync as statSync17 } from "node:fs";
244566
- import { isAbsolute as isAbsolute3, join as join55, relative as relative11, resolve as resolve28 } from "node:path";
244576
+ import { isAbsolute as isAbsolute3, join as join56, relative as relative11, resolve as resolve28 } from "node:path";
244567
244577
  var SCREEN_EXTS = [".ts", ".tsx", ".js", ".jsx", ".mjs"];
244568
244578
  var SCREEN_ENTRY_PATH = "/.screen-entry.ts";
244569
244579
  var DEFAULT_DESIGN_DIR = "design";
@@ -244571,7 +244581,7 @@ var hasSeparator = (file) => file.includes("/") || file.includes("\\");
244571
244581
  var findScreenFile = (root, file, dirFlag) => {
244572
244582
  const candidates = [resolve28(process.cwd(), file)];
244573
244583
  if (!hasSeparator(file)) {
244574
- candidates.push(join55(root, (dirFlag ?? DEFAULT_DESIGN_DIR).replace(/[/\\]+$/, ""), "screens", file));
244584
+ candidates.push(join56(root, (dirFlag ?? DEFAULT_DESIGN_DIR).replace(/[/\\]+$/, ""), "screens", file));
244575
244585
  }
244576
244586
  for (const base of candidates) {
244577
244587
  if (existsSync49(base) && statSync17(base).isFile())
@@ -244586,8 +244596,8 @@ var designDirOf = (root, key) => {
244586
244596
  const m = /^\/(.*)screens\/([^/]+)\.[^./]+$/.exec(key);
244587
244597
  if (!m)
244588
244598
  return null;
244589
- const dir = join55(root, m[1]);
244590
- return existsSync49(join55(dir, "meta.json")) ? { dir, id: m[2] } : null;
244599
+ const dir = join56(root, m[1]);
244600
+ return existsSync49(join56(dir, "meta.json")) ? { dir, id: m[2] } : null;
244591
244601
  };
244592
244602
  var resolveScreenTarget = (root, file, opts = {}) => {
244593
244603
  const abs = findScreenFile(root, file, opts.dir);
@@ -244634,7 +244644,7 @@ init_manifest();
244634
244644
  init_cli();
244635
244645
  import { existsSync as existsSync50, mkdirSync as mkdirSync30, mkdtempSync as mkdtempSync6, rmSync as rmSync15, writeFileSync as writeFileSync32 } from "node:fs";
244636
244646
  import { tmpdir as tmpdir6 } from "node:os";
244637
- import { join as join56, resolve as resolve29 } from "node:path";
244647
+ import { join as join57, resolve as resolve29 } from "node:path";
244638
244648
  import { deflateSync as deflateSync2 } from "node:zlib";
244639
244649
  var MAX_SIDE = 4096;
244640
244650
  var crcTable = (() => {
@@ -244687,7 +244697,7 @@ var madeDir = null;
244687
244697
  var made = 0;
244688
244698
  var write = (name, bytes) => {
244689
244699
  if (!madeDir) {
244690
- madeDir = mkdtempSync6(join56(tmpdir6(), "lecodes-pick-"));
244700
+ madeDir = mkdtempSync6(join57(tmpdir6(), "lecodes-pick-"));
244691
244701
  const dir = madeDir;
244692
244702
  process.on("exit", () => {
244693
244703
  try {
@@ -244695,9 +244705,9 @@ var write = (name, bytes) => {
244695
244705
  } catch {}
244696
244706
  });
244697
244707
  }
244698
- const dir = join56(madeDir, String(made++));
244708
+ const dir = join57(madeDir, String(made++));
244699
244709
  mkdirSync30(dir);
244700
- const path = join56(dir, name);
244710
+ const path = join57(dir, name);
244701
244711
  writeFileSync32(path, bytes);
244702
244712
  return path;
244703
244713
  };
@@ -245382,7 +245392,7 @@ var requireRenderer = async () => loadPeer("lecodes-headless", "headless", { for
245382
245392
  var fileScenarioIO = (dir) => ({
245383
245393
  write: (relPath, data) => {
245384
245394
  const abs = resolve31(dir, relPath);
245385
- mkdirSync31(dirname25(abs), { recursive: true });
245395
+ mkdirSync31(dirname26(abs), { recursive: true });
245386
245396
  writeFileSync33(abs, data);
245387
245397
  }
245388
245398
  });
@@ -245411,13 +245421,13 @@ var readScenarioFile = (path) => {
245411
245421
  throw new CliError(`Can't read scenario "${path}": ${e instanceof Error ? e.message : String(e)}`);
245412
245422
  }
245413
245423
  if (Array.isArray(raw))
245414
- return { steps: resolvePicks(raw, dirname25(resolve31(path))) };
245424
+ return { steps: resolvePicks(raw, dirname26(resolve31(path))) };
245415
245425
  if (typeof raw !== "object" || raw === null)
245416
245426
  throw new CliError(`Scenario "${path}" must be a JSON object with "steps" (or a bare step array).`);
245417
245427
  const file = raw;
245418
245428
  if (file.steps === undefined)
245419
245429
  throw new CliError(`Scenario "${path}" has no "steps".`);
245420
- return { ...file, steps: resolvePicks(file.steps, dirname25(resolve31(path))) };
245430
+ return { ...file, steps: resolvePicks(file.steps, dirname26(resolve31(path))) };
245421
245431
  };
245422
245432
  var parseClip = (raw) => {
245423
245433
  if (raw === undefined)
@@ -245542,13 +245552,13 @@ var renderDesktop = async (flags, file) => {
245542
245552
  entryOverride: screen?.entryPath
245543
245553
  });
245544
245554
  if (!sim)
245545
- mkdirSync31(dirname25(resolve31(pngFlag)), { recursive: true });
245555
+ mkdirSync31(dirname26(resolve31(pngFlag)), { recursive: true });
245546
245556
  if (scenario) {
245547
245557
  const outDir = flags["out-dir"];
245548
245558
  const plan = translateScenario(scenario.steps, { outDir, headroomFrames: frames, sim });
245549
245559
  for (const st of plan.steps)
245550
245560
  if (st.screenshot)
245551
- mkdirSync31(dirname25(st.screenshot), { recursive: true });
245561
+ mkdirSync31(dirname26(st.screenshot), { recursive: true });
245552
245562
  const timeoutMs = flags.timeout || 60000 + plan.steps.length * 5000;
245553
245563
  const label = sim ? "sim" : "native";
245554
245564
  note(`Running ${plan.steps.length} step${plan.steps.length === 1 ? "" : "s"} (${label})…`);
@@ -245638,7 +245648,7 @@ var renderHeadless = async (flags, file) => {
245638
245648
  const width = flags.width || scenario?.width || screen?.frame?.[0] || projectViewport?.width || 390;
245639
245649
  const height = flags.height || scenario?.height || screen?.frame?.[1] || projectViewport?.height || 844;
245640
245650
  const onConsole = flags.logs ? (level, text) => logErr(`${c.dim(`[${level}]`)} ${text}`) : undefined;
245641
- const envelopeFixtures = resolveFixtures(scenario?.fixtures, flags.script !== undefined ? dirname25(resolve31(flags.script)) : ".");
245651
+ const envelopeFixtures = resolveFixtures(scenario?.fixtures, flags.script !== undefined ? dirname26(resolve31(flags.script)) : ".");
245642
245652
  const flagFixtures = resolveFixtures(flags.fixtures, ".");
245643
245653
  const fixtures = envelopeFixtures || flagFixtures ? { ...envelopeFixtures, ...flagFixtures } : undefined;
245644
245654
  if (fixtures) {
@@ -245700,7 +245710,7 @@ var renderHeadless = async (flags, file) => {
245700
245710
  for (const w of [...warnings, ...mapWarnings])
245701
245711
  warnErr(w);
245702
245712
  const pngPath = mapFlag.endsWith(".png") ? mapFlag : mapFlag + ".png";
245703
- mkdirSync31(dirname25(resolve31(pngPath)), { recursive: true });
245713
+ mkdirSync31(dirname26(resolve31(pngPath)), { recursive: true });
245704
245714
  writeFileSync33(resolve31(pngPath), png);
245705
245715
  const jsonPath = pngPath.slice(0, -4) + ".json";
245706
245716
  writeFileSync33(resolve31(jsonPath), JSON.stringify(data, null, 2));
@@ -245723,7 +245733,7 @@ var renderHeadless = async (flags, file) => {
245723
245733
  if (isNullSink(pngFlag)) {
245724
245734
  note(`Discarded PNG (${pngFlag})`);
245725
245735
  } else {
245726
- mkdirSync31(dirname25(resolve31(pngFlag)), { recursive: true });
245736
+ mkdirSync31(dirname26(resolve31(pngFlag)), { recursive: true });
245727
245737
  writeFileSync33(resolve31(pngFlag), png);
245728
245738
  note(`Wrote ${pngFlag} (${png.length} bytes, ${outW}x${outH}${clip !== undefined ? ", clipped" : ""})`);
245729
245739
  }
@@ -245752,7 +245762,7 @@ var renderHeadless = async (flags, file) => {
245752
245762
  // src/commands/scene.ts
245753
245763
  init_cli();
245754
245764
  import { existsSync as existsSync52, readFileSync as readFileSync46, readdirSync as readdirSync22, statSync as statSync18, writeFileSync as writeFileSync35 } from "node:fs";
245755
- import { basename as basename24, dirname as dirname26, join as join58, relative as relative12, resolve as resolve32 } from "node:path";
245765
+ import { basename as basename24, dirname as dirname27, join as join59, relative as relative12, resolve as resolve32 } from "node:path";
245756
245766
 
245757
245767
  // src/compile/sceneCompile.ts
245758
245768
  init_env2();
@@ -245762,7 +245772,7 @@ init_cli();
245762
245772
  init_projectCompile();
245763
245773
  import { createHash as createHash9 } from "node:crypto";
245764
245774
  import { existsSync as existsSync51, mkdirSync as mkdirSync32, readFileSync as readFileSync45, writeFileSync as writeFileSync34 } from "node:fs";
245765
- import { join as join57 } from "node:path";
245775
+ import { join as join58 } from "node:path";
245766
245776
  var TEXT_EXT = /\.(ts|js|json|svg|txt|md)$/i;
245767
245777
  var rel = (key) => key.replace(/^\//, "");
245768
245778
  var compileSceneEditor = async (opts) => {
@@ -245793,8 +245803,8 @@ var compileSceneEditor = async (opts) => {
245793
245803
  const dir = shadersCacheDir(root);
245794
245804
  mkdirSync32(dir, { recursive: true });
245795
245805
  const liteName = `${hash}_webgl-lite.filamat`;
245796
- if (!existsSync51(join57(dir, liteName)))
245797
- writeFileSync34(join57(dir, liteName), JSON.stringify(buildLiteMaterialArtifact(e.text ?? "")));
245806
+ if (!existsSync51(join58(dir, liteName)))
245807
+ writeFileSync34(join58(dir, liteName), JSON.stringify(buildLiteMaterialArtifact(e.text ?? "")));
245798
245808
  const src = `/project/.lecodes/shaders/${hash}_opengl.filamat`;
245799
245809
  e.shaders = ["opengl", "webgl-lite"].map((platform) => ({ platform, src }));
245800
245810
  }
@@ -245832,9 +245842,9 @@ var DEFAULT_PORT3 = 4488;
245832
245842
  var findAppRoot = (start) => {
245833
245843
  let dir = start;
245834
245844
  while (true) {
245835
- if (existsSync52(join58(dir, "app.json")))
245845
+ if (existsSync52(join59(dir, "app.json")))
245836
245846
  return dir;
245837
- const parent = dirname26(dir);
245847
+ const parent = dirname27(dir);
245838
245848
  if (parent === dir)
245839
245849
  return null;
245840
245850
  dir = parent;
@@ -245861,7 +245871,7 @@ var getContext2 = (pathArg) => {
245861
245871
  if (existsSync52(abs) && statSync18(abs).isDirectory())
245862
245872
  root = abs;
245863
245873
  else if (abs.endsWith(".scene.ts") && existsSync52(abs))
245864
- root = findAppRoot(dirname26(abs)) ?? dirname26(abs);
245874
+ root = findAppRoot(dirname27(abs)) ?? dirname27(abs);
245865
245875
  else
245866
245876
  throw new CliError(`No such folder or .scene.ts: ${pathArg}`);
245867
245877
  } else {
@@ -245878,7 +245888,7 @@ var getContext2 = (pathArg) => {
245878
245888
  return { root, manifest, name: manifest?.name ?? basename24(root), scene };
245879
245889
  };
245880
245890
  var writeMcpConfig2 = (root, port) => {
245881
- const path = join58(root, ".mcp.json");
245891
+ const path = join59(root, ".mcp.json");
245882
245892
  const entry = { type: "http", url: `http://localhost:${port}/mcp` };
245883
245893
  let config = {};
245884
245894
  if (existsSync52(path)) {
@@ -245905,7 +245915,7 @@ var countScenes = (dir) => {
245905
245915
  for (const name of readdirSync22(dir)) {
245906
245916
  if (name === "node_modules" || name.startsWith("."))
245907
245917
  continue;
245908
- const full = join58(dir, name);
245918
+ const full = join59(dir, name);
245909
245919
  if (statSync18(full).isDirectory())
245910
245920
  n += countScenes(full);
245911
245921
  else if (name.endsWith(".scene.ts"))
@@ -246009,14 +246019,14 @@ init_compile();
246009
246019
  init_distRoot();
246010
246020
  init_cli();
246011
246021
  import { existsSync as existsSync53, mkdirSync as mkdirSync33, readdirSync as readdirSync23, readFileSync as readFileSync47, writeFileSync as writeFileSync36 } from "node:fs";
246012
- import { basename as basename26, join as join59, relative as relative13, resolve as resolve33 } from "node:path";
246022
+ import { basename as basename26, join as join60, relative as relative13, resolve as resolve33 } from "node:path";
246013
246023
  var engineMaterialsDir = () => {
246014
246024
  const candidates = [
246015
- join59(distRoot, "runtime", "materials"),
246016
- join59(distRoot, "..", "..", "engines", "gl", "materials", "src")
246025
+ join60(distRoot, "runtime", "materials"),
246026
+ join60(distRoot, "..", "..", "engines", "gl", "materials", "src")
246017
246027
  ];
246018
246028
  for (const c of candidates)
246019
- if (existsSync53(join59(c, "unlit.mat")))
246029
+ if (existsSync53(join60(c, "unlit.mat")))
246020
246030
  return c;
246021
246031
  return null;
246022
246032
  };
@@ -246099,7 +246109,7 @@ var writeNewShader = (o) => {
246099
246109
  if (!NAME_RE.test(name))
246100
246110
  throw new CliError(`"${o.name}" is not a shader name — letters, digits, - and _ (starting with a letter), e.g. hologram or rim-light`);
246101
246111
  const dir = resolve33(o.cwd ?? process.cwd(), o.dir ?? ".");
246102
- const matPath = join59(dir, `${name}.mat`), assetPath = join59(dir, `${name}.material.ts`);
246112
+ const matPath = join60(dir, `${name}.mat`), assetPath = join60(dir, `${name}.material.ts`);
246103
246113
  if (!o.force) {
246104
246114
  for (const p of [matPath, assetPath])
246105
246115
  if (existsSync53(p))
@@ -246115,7 +246125,7 @@ var writeNewShader = (o) => {
246115
246125
  const known = engineMaterialNames();
246116
246126
  if (!known.includes(ref))
246117
246127
  throw new CliError(`no engine material "${ref}". Known: ${known.join(", ")}`);
246118
- mat = refMat(name, ref, readFileSync47(join59(srcDir, `${ref}.mat`), "utf8"));
246128
+ mat = refMat(name, ref, readFileSync47(join60(srcDir, `${ref}.mat`), "utf8"));
246119
246129
  } else
246120
246130
  mat = starterMat(name);
246121
246131
  mkdirSync33(dir, { recursive: true });
@@ -246268,7 +246278,7 @@ var shaders_default = defineCommand({
246268
246278
  // src/commands/level.ts
246269
246279
  import { existsSync as existsSync54, mkdtempSync as mkdtempSync7, rmSync as rmSync16 } from "node:fs";
246270
246280
  import { tmpdir as tmpdir7 } from "node:os";
246271
- import { basename as basename27, dirname as dirname27, join as join60, resolve as resolve34 } from "node:path";
246281
+ import { basename as basename27, dirname as dirname28, join as join61, resolve as resolve34 } from "node:path";
246272
246282
  init_cli();
246273
246283
  init_shared();
246274
246284
  var build2 = defineCommand({
@@ -246317,14 +246327,14 @@ import ${JSON.stringify(importPath)}
246317
246327
  const navFiles = resources.filter((r) => !r.remote && r.absPath && named.has(r.name)).map((r) => r.absPath);
246318
246328
  let navOut = null, navName = null;
246319
246329
  if (navFiles.length === 1) {
246320
- navOut = dirname27(navFiles[0]);
246330
+ navOut = dirname28(navFiles[0]);
246321
246331
  navName = basename27(navFiles[0]).replace(/\.navmesh$/, "");
246322
246332
  ({ js, resources } = await compile(navOut, navName));
246323
246333
  } else if (navFiles.length > 1) {
246324
246334
  throw new CliError(`${entryFile} reaches ${navFiles.length} navmesh files (${navFiles.map((f) => basename27(f)).join(", ")}) — build one level per entry.`);
246325
246335
  }
246326
- const scratch = mkdtempSync7(join60(tmpdir7(), "lecodes-level-"));
246327
- const outPng = join60(scratch, "frame.png");
246336
+ const scratch = mkdtempSync7(join61(tmpdir7(), "lecodes-level-"));
246337
+ const outPng = join61(scratch, "frame.png");
246328
246338
  note(`Loading the level through the ${host} host: the static cache${navName ? `, the collision geometry for ${navName}.navmesh` : ""}…`);
246329
246339
  let output = "";
246330
246340
  try {
@@ -246418,7 +246428,7 @@ var status_default2 = defineCommand({
246418
246428
 
246419
246429
  // src/commands/test.ts
246420
246430
  import { existsSync as existsSync56, mkdirSync as mkdirSync35, readFileSync as readFileSync49, readdirSync as readdirSync24 } from "node:fs";
246421
- import { dirname as dirname29, resolve as resolve35 } from "node:path";
246431
+ import { dirname as dirname30, resolve as resolve35 } from "node:path";
246422
246432
  init_manifest();
246423
246433
 
246424
246434
  // src/hosts/liteRunner.ts
@@ -246426,7 +246436,7 @@ init_cli();
246426
246436
  import { spawn as spawn7 } from "node:child_process";
246427
246437
  import { existsSync as existsSync55, mkdirSync as mkdirSync34, rmSync as rmSync17, writeFileSync as writeFileSync37 } from "node:fs";
246428
246438
  import { createServer as createServer3 } from "node:net";
246429
- import { dirname as dirname28, join as join61 } from "node:path";
246439
+ import { dirname as dirname29, join as join62 } from "node:path";
246430
246440
  import { createInterface as createInterface2 } from "node:readline";
246431
246441
  init_manifest();
246432
246442
  init_distRoot();
@@ -246436,7 +246446,7 @@ var LOG_SLACK_MS = 3000;
246436
246446
  var NO_NODE = "--lite needs Node on the PATH: the browser is driven from a Node process.";
246437
246447
  var NO_PLAYWRIGHT = "--lite runs the flows in a browser and needs Playwright: `npm install -D playwright` in the project, then `npx playwright install chromium` once.";
246438
246448
  var startDriver = async () => {
246439
- const script = join61(distRoot, "src", "hosts", "liteBrowser.mjs");
246449
+ const script = join62(distRoot, "src", "hosts", "liteBrowser.mjs");
246440
246450
  if (!existsSync55(script))
246441
246451
  throw new CliError("--lite is not available in this build of the CLI (its browser driver ships with the npm package).");
246442
246452
  const child = spawn7("node", [script], { stdio: ["pipe", "pipe", "inherit"] });
@@ -246483,10 +246493,10 @@ var startDriver = async () => {
246483
246493
  `);
246484
246494
  });
246485
246495
  const from = [
246486
- join61(process.cwd(), "package.json"),
246487
- join61(distRoot, "package.json"),
246488
- join61(peersDir(), "package.json"),
246489
- join61(distRoot, "..", "..", "engines", "gl-lite", "package.json")
246496
+ join62(process.cwd(), "package.json"),
246497
+ join62(distRoot, "package.json"),
246498
+ join62(peersDir(), "package.json"),
246499
+ join62(distRoot, "..", "..", "engines", "gl-lite", "package.json")
246490
246500
  ];
246491
246501
  try {
246492
246502
  await call("launch", { from });
@@ -246527,7 +246537,7 @@ var freePort = () => new Promise((resolve, reject) => {
246527
246537
  });
246528
246538
  var startLiteSession = async (options) => {
246529
246539
  const port = await freePort();
246530
- const dbDir = join61(options.root, LECODES_DIR, "test-db");
246540
+ const dbDir = join62(options.root, LECODES_DIR, "test-db");
246531
246541
  rmSync17(dbDir, { recursive: true, force: true });
246532
246542
  rmSync17(filesDirOf(dbDir), { recursive: true, force: true });
246533
246543
  let ran = 0;
@@ -246808,7 +246818,7 @@ var runPlan = async (driver, url, plan, options, page) => {
246808
246818
  return;
246809
246819
  case "dump": {
246810
246820
  const file = rest.trim();
246811
- mkdirSync34(dirname28(file), { recursive: true });
246821
+ mkdirSync34(dirname29(file), { recursive: true });
246812
246822
  writeFileSync37(file, await dump());
246813
246823
  return;
246814
246824
  }
@@ -246829,7 +246839,7 @@ var runPlan = async (driver, url, plan, options, page) => {
246829
246839
  }
246830
246840
  case "shot": {
246831
246841
  const file = rest.trim();
246832
- mkdirSync34(dirname28(file), { recursive: true });
246842
+ mkdirSync34(dirname29(file), { recursive: true });
246833
246843
  await driver.screenshot(file, clip);
246834
246844
  return;
246835
246845
  }
@@ -246939,7 +246949,7 @@ var readFlowFile = (abs, displayName) => {
246939
246949
  throw new CliError(`Can't read "${displayName}": ${e instanceof Error ? e.message : String(e)}`);
246940
246950
  }
246941
246951
  if (Array.isArray(raw))
246942
- return { name: displayName, kind: "file", steps: resolvePicks(raw, dirname29(abs)) };
246952
+ return { name: displayName, kind: "file", steps: resolvePicks(raw, dirname30(abs)) };
246943
246953
  if (typeof raw !== "object" || raw === null || raw.steps === undefined) {
246944
246954
  throw new CliError(`"${displayName}" must be a JSON object with "steps" (or a bare step array).`);
246945
246955
  }
@@ -246947,8 +246957,8 @@ var readFlowFile = (abs, displayName) => {
246947
246957
  return {
246948
246958
  name: file.name ?? displayName,
246949
246959
  kind: "file",
246950
- steps: resolvePicks(file.steps, dirname29(abs)),
246951
- fixtures: resolveFixtures(file.fixtures, dirname29(abs)),
246960
+ steps: resolvePicks(file.steps, dirname30(abs)),
246961
+ fixtures: resolveFixtures(file.fixtures, dirname30(abs)),
246952
246962
  width: file.width,
246953
246963
  height: file.height,
246954
246964
  settle: file.settle,
@@ -247117,7 +247127,7 @@ var runTests = async (args, flags) => {
247117
247127
  const plan = translateScenario(kase.steps, { outDir: caseDir, headroomFrames: nativeFrames, sim });
247118
247128
  for (const st of plan.steps)
247119
247129
  if (st.screenshot)
247120
- mkdirSync35(dirname29(st.screenshot), { recursive: true });
247130
+ mkdirSync35(dirname30(st.screenshot), { recursive: true });
247121
247131
  mkdirSync35(caseDir, { recursive: true });
247122
247132
  const finalPng = resolve35(caseDir, "final.png");
247123
247133
  const { output } = await runDesktopRender(native.js, native.resources, {
@@ -247283,7 +247293,7 @@ import { createRequire as createRequire8 } from "node:module";
247283
247293
  import { execFileSync as execFileSync8 } from "node:child_process";
247284
247294
  import { existsSync as existsSync57, mkdtempSync as mkdtempSync8, readdirSync as readdirSync25, rmSync as rmSync18, statSync as statSync19 } from "node:fs";
247285
247295
  import { tmpdir as tmpdir8 } from "node:os";
247286
- import { extname, join as join62, relative as relative15, resolve as resolve36 } from "node:path";
247296
+ import { extname, join as join63, relative as relative15, resolve as resolve36 } from "node:path";
247287
247297
  init_cli();
247288
247298
  init_paths();
247289
247299
  var DEFAULT_SIZE = 256;
@@ -247295,8 +247305,8 @@ var findKtx = () => {
247295
247305
  process.env.LECODES_KTX,
247296
247306
  process.env.KTX_CLI,
247297
247307
  process.env.KTX_TOKTX?.replace(/toktx(\.exe)?$/i, exe),
247298
- process.platform === "win32" ? join62(process.env.LOCALAPPDATA ?? "", "Programs", "KTX-Software", "bin", exe) : null,
247299
- process.platform === "win32" ? join62(process.env.ProgramFiles ?? "", "KTX-Software", "bin", exe) : null,
247308
+ process.platform === "win32" ? join63(process.env.LOCALAPPDATA ?? "", "Programs", "KTX-Software", "bin", exe) : null,
247309
+ process.platform === "win32" ? join63(process.env.ProgramFiles ?? "", "KTX-Software", "bin", exe) : null,
247300
247310
  "/usr/local/bin/ktx",
247301
247311
  "/opt/homebrew/bin/ktx"
247302
247312
  ].filter((p) => !!p);
@@ -247342,7 +247352,7 @@ var collect = (dir) => {
247342
247352
  for (const name of readdirSync25(dir)) {
247343
247353
  if (name === "node_modules" || name.startsWith("."))
247344
247354
  continue;
247345
- const full = join62(dir, name);
247355
+ const full = join63(dir, name);
247346
247356
  if (statSync19(full).isDirectory())
247347
247357
  out.push(...collect(full));
247348
247358
  else if (IMAGE_EXT.test(name))
@@ -247391,7 +247401,7 @@ var thumbs = async (targets, size, force) => {
247391
247401
  const ktx = files.some((f) => f.toLowerCase().endsWith(".ktx2")) ? findKtx() : null;
247392
247402
  const sharp = sharpResizer();
247393
247403
  const resize = sharp ?? jimpResizer();
247394
- const tmp = mkdtempSync8(join62(tmpdir8(), "lecodes-thumbs-"));
247404
+ const tmp = mkdtempSync8(join63(tmpdir8(), "lecodes-thumbs-"));
247395
247405
  let made = 0, fresh = 0;
247396
247406
  const skipped = [];
247397
247407
  try {
@@ -247417,7 +247427,7 @@ var thumbs = async (targets, size, force) => {
247417
247427
  skipped.push(`${asset} (KTX2 needs KTX-Software's \`ktx\` — set LECODES_KTX or put it on PATH)`);
247418
247428
  continue;
247419
247429
  }
247420
- source = join62(tmp, `${i}.png`);
247430
+ source = join63(tmp, `${i}.png`);
247421
247431
  ktxToPng(ktx, file, source);
247422
247432
  }
247423
247433
  sceneServer.writePreviewFile(root, asset, await resize(source, size));
@@ -247437,7 +247447,7 @@ var thumbs = async (targets, size, force) => {
247437
247447
  if (rendered.length > 0) {
247438
247448
  warnErr(`Models, materials and prefabs are RENDERED, not decoded — the scene editor does those: ${rendered.join(", ")}`);
247439
247449
  }
247440
- note(`Cache: ${join62(root, ".lecodes", "preview")} (re-runs skip everything unchanged)`);
247450
+ note(`Cache: ${join63(root, ".lecodes", "preview")} (re-runs skip everything unchanged)`);
247441
247451
  };
247442
247452
 
247443
247453
  // src/commands/update/index.ts
@@ -247450,7 +247460,7 @@ init_packageManager();
247450
247460
  import { spawnSync as spawnSync12 } from "node:child_process";
247451
247461
  import { existsSync as existsSync58, readdirSync as readdirSync26, readFileSync as readFileSync50 } from "node:fs";
247452
247462
  import { homedir as homedir15 } from "node:os";
247453
- import { dirname as dirname30, join as join63, resolve as resolve38 } from "node:path";
247463
+ import { dirname as dirname31, join as join64, resolve as resolve38 } from "node:path";
247454
247464
 
247455
247465
  // src/commands/update/types.ts
247456
247466
  init_api();
@@ -247522,9 +247532,9 @@ var findProjectDir = (start) => {
247522
247532
  const home = resolve38(homedir15());
247523
247533
  let dir = resolve38(start);
247524
247534
  while (true) {
247525
- if (dir !== home && (existsSync58(join63(dir, "app.json")) || existsSync58(join63(dir, ".lecodes", "manifest.json")) || existsSync58(join63(dir, ".lecodes", "types"))))
247535
+ if (dir !== home && (existsSync58(join64(dir, "app.json")) || existsSync58(join64(dir, ".lecodes", "manifest.json")) || existsSync58(join64(dir, ".lecodes", "types"))))
247526
247536
  return dir;
247527
- const parent = dirname30(dir);
247537
+ const parent = dirname31(dir);
247528
247538
  if (parent === dir)
247529
247539
  return null;
247530
247540
  dir = parent;
@@ -247590,13 +247600,13 @@ var npmNewestIn = async (name, range) => {
247590
247600
  };
247591
247601
  var cliVersionAt = (entry) => {
247592
247602
  try {
247593
- return JSON.parse(readFileSync50(join63(dirname30(entry), "..", "package.json"), "utf8")).version ?? null;
247603
+ return JSON.parse(readFileSync50(join64(dirname31(entry), "..", "package.json"), "utf8")).version ?? null;
247594
247604
  } catch {
247595
247605
  return null;
247596
247606
  }
247597
247607
  };
247598
247608
  var FROM_SOURCE = /[\\/]src[\\/]commands[\\/]/.test(import.meta.url);
247599
- var STANDALONE = existsSync58(join63(dirname30(process.execPath), "runtime")) && existsSync58(join63(dirname30(process.execPath), process.platform === "win32" ? "chisel.exe" : "chisel"));
247609
+ var STANDALONE = existsSync58(join64(dirname31(process.execPath), "runtime")) && existsSync58(join64(dirname31(process.execPath), process.platform === "win32" ? "chisel.exe" : "chisel"));
247600
247610
  var update_default = defineCommand({
247601
247611
  name: "update",
247602
247612
  summary: "Move everything the project depends on to its newest published state",
@@ -247708,7 +247718,7 @@ ${c.bold(name)} ${c.dim(what)}`);
247708
247718
  return ["skipped", "not inside a project"];
247709
247719
  if (flags["no-shells"])
247710
247720
  return ["skipped", "--no-shells"];
247711
- const present = ["ios", "android"].filter((d) => existsSync58(join63(root, d)) && readdirSync26(join63(root, d)).length > 0);
247721
+ const present = ["ios", "android"].filter((d) => existsSync58(join64(root, d)) && readdirSync26(join64(root, d)).length > 0);
247712
247722
  if (present.length === 0)
247713
247723
  return ["skipped", "no ios/ or android/ shell in this project (`lecodes app init ios|android`)"];
247714
247724
  await runSubcommand(app_default, "update");
@@ -247795,7 +247805,7 @@ init_env2();
247795
247805
  init_compile();
247796
247806
  import { createHash as createHash10 } from "node:crypto";
247797
247807
  import { copyFileSync as copyFileSync2, cpSync as cpSync7, existsSync as existsSync59, mkdirSync as mkdirSync36, readFileSync as readFileSync51, readdirSync as readdirSync27, rmSync as rmSync19, statSync as statSync20, writeFileSync as writeFileSync38 } from "node:fs";
247798
- import { dirname as dirname31, extname as extname2, join as join64, resolve as resolve39 } from "node:path";
247808
+ import { dirname as dirname32, extname as extname2, join as join65, resolve as resolve39 } from "node:path";
247799
247809
  init_fonts();
247800
247810
  init_assetIcons();
247801
247811
  init_projectCompile();
@@ -247808,7 +247818,7 @@ var normalBase = (base) => {
247808
247818
  var walk = (dir, prefix = "") => {
247809
247819
  const out = [];
247810
247820
  for (const name of readdirSync27(dir)) {
247811
- const abs = join64(dir, name);
247821
+ const abs = join65(dir, name);
247812
247822
  const stat = statSync20(abs);
247813
247823
  if (stat.isDirectory())
247814
247824
  out.push(...walk(abs, `${prefix}${name}/`));
@@ -247837,21 +247847,21 @@ var assembleLitePage = (dist, out, opts) => {
247837
247847
  }
247838
247848
  const listed = listedPlugins(js);
247839
247849
  cpSync7(dist, out, { recursive: true });
247840
- const table = join64(out, "features.json");
247850
+ const table = join65(out, "features.json");
247841
247851
  if (existsSync59(table)) {
247842
247852
  const { features, fonts } = JSON.parse(readFileSync51(table, "utf8"));
247843
247853
  if (config.font === "system")
247844
247854
  for (const file of fonts ?? [])
247845
- rmSync19(join64(out, file), { force: true });
247855
+ rmSync19(join65(out, file), { force: true });
247846
247856
  for (const feature of features) {
247847
247857
  if (feature.uses.some((name) => js.includes(name)))
247848
247858
  continue;
247849
247859
  for (const file of feature.files)
247850
- rmSync19(join64(out, file), { force: true });
247860
+ rmSync19(join65(out, file), { force: true });
247851
247861
  }
247852
247862
  rmSync19(table);
247853
247863
  }
247854
- const pluginsTable = join64(out, "plugins.json");
247864
+ const pluginsTable = join65(out, "plugins.json");
247855
247865
  if (existsSync59(pluginsTable) || halves.length > 0) {
247856
247866
  const { plugins } = existsSync59(pluginsTable) ? JSON.parse(readFileSync51(pluginsTable, "utf8")) : { plugins: {} };
247857
247867
  const kept = {};
@@ -247859,15 +247869,15 @@ var assembleLitePage = (dist, out, opts) => {
247859
247869
  if (listed.has(id))
247860
247870
  kept[id] = plugins[id];
247861
247871
  else
247862
- rmSync19(join64(out, "plugins", id), { recursive: true, force: true });
247872
+ rmSync19(join65(out, "plugins", id), { recursive: true, force: true });
247863
247873
  }
247864
247874
  for (const { half, js } of halves) {
247865
247875
  if (half.folder in plugins && half.folder in kept)
247866
247876
  throw new CliError(`Plugin "${half.id}": its half's folder is named like the "${half.folder}" plugin the page carries — rename ${half.dir}.`);
247867
- const dir = join64(out, "plugins", half.folder);
247877
+ const dir = join65(out, "plugins", half.folder);
247868
247878
  mkdirSync36(dir, { recursive: true });
247869
- writeFileSync38(join64(dir, "index.js"), js);
247870
- copyStatic(half, join64(out, "plugins"));
247879
+ writeFileSync38(join65(dir, "index.js"), js);
247880
+ copyStatic(half, join65(out, "plugins"));
247871
247881
  const firstParty = plugins[half.id];
247872
247882
  kept[half.id] = firstParty !== undefined && listed.has(half.id) ? [halfModule(half), firstParty] : halfModule(half);
247873
247883
  }
@@ -247878,16 +247888,16 @@ var assembleLitePage = (dist, out, opts) => {
247878
247888
  writeFileSync38(pluginsTable, JSON.stringify({ plugins: kept }, null, 2));
247879
247889
  else {
247880
247890
  rmSync19(pluginsTable, { force: true });
247881
- rmSync19(join64(out, "plugins"), { recursive: true, force: true });
247891
+ rmSync19(join65(out, "plugins"), { recursive: true, force: true });
247882
247892
  }
247883
247893
  }
247884
- let html = readFileSync51(join64(dist, "index.html"), "utf8");
247894
+ let html = readFileSync51(join65(dist, "index.html"), "utf8");
247885
247895
  const head = [];
247886
247896
  head.push(`<meta name="theme-color" content="${escapeHtml(config.themeColor ?? "#000000")}" />`);
247887
247897
  if (opts.icon) {
247888
247898
  if (existsSync59(opts.icon.file)) {
247889
247899
  const file = `icon${extname2(opts.icon.file).toLowerCase() || ".png"}`;
247890
- copyFileSync2(opts.icon.file, join64(out, file));
247900
+ copyFileSync2(opts.icon.file, join65(out, file));
247891
247901
  head.push(`<link rel="icon" href="${file}" />`, `<link rel="apple-touch-icon" href="${file}" />`);
247892
247902
  } else {
247893
247903
  warnings.push(`app.json icon "${opts.icon.declared}" is not there — the page has no icon`);
@@ -247913,9 +247923,9 @@ var assembleLitePage = (dist, out, opts) => {
247913
247923
  </head>`);
247914
247924
  if (config.lang)
247915
247925
  replace(/<html lang="[^"]*">/, `<html lang="${escapeHtml(config.lang)}">`);
247916
- writeFileSync38(join64(out, "index.html"), html);
247926
+ writeFileSync38(join65(out, "index.html"), html);
247917
247927
  if (mode === "path")
247918
- writeFileSync38(join64(out, "404.html"), html);
247928
+ writeFileSync38(join65(out, "404.html"), html);
247919
247929
  return warnings;
247920
247930
  };
247921
247931
  var copyNamedAssets = (entries, js, out) => {
@@ -247925,12 +247935,12 @@ var copyNamedAssets = (entries, js, out) => {
247925
247935
  continue;
247926
247936
  if (!js.includes(entry.fileSrc))
247927
247937
  continue;
247928
- const to = join64(out, "assets", ...entry.path.split("/").filter(Boolean));
247938
+ const to = join65(out, "assets", ...entry.path.split("/").filter(Boolean));
247929
247939
  if (existsSync59(to)) {
247930
247940
  warnings.push(`${entry.path}: a file of the page has this name in the built folder — the project's file was not copied`);
247931
247941
  continue;
247932
247942
  }
247933
- mkdirSync36(dirname31(to), { recursive: true });
247943
+ mkdirSync36(dirname32(to), { recursive: true });
247934
247944
  copyFileSync2(entry.absPath, to);
247935
247945
  }
247936
247946
  return warnings;
@@ -248001,13 +248011,13 @@ var buildWeb = async (options) => {
248001
248011
  halves,
248002
248012
  icon: app?.icon ? { file: resolve39(root, app.icon), declared: app.icon } : null
248003
248013
  }));
248004
- writeFileSync38(join64(out, bundle), js);
248014
+ writeFileSync38(join65(out, bundle), js);
248005
248015
  warnings.push(...copyNamedAssets(entries, js, out));
248006
248016
  for (const [hash, artifact] of shaders) {
248007
248017
  if (!js.includes(`shaders/${hash}_`))
248008
248018
  continue;
248009
- mkdirSync36(join64(out, "shaders"), { recursive: true });
248010
- writeFileSync38(join64(out, "shaders", `${hash}_webgl-lite.filamat`), artifact);
248019
+ mkdirSync36(join65(out, "shaders"), { recursive: true });
248020
+ writeFileSync38(join65(out, "shaders", `${hash}_webgl-lite.filamat`), artifact);
248011
248021
  }
248012
248022
  return { out, bundle, files: walk(out), warnings };
248013
248023
  };
@@ -248015,10 +248025,10 @@ var buildWeb = async (options) => {
248015
248025
  // src/web/preview.ts
248016
248026
  import { createReadStream as createReadStream3, existsSync as existsSync60, statSync as statSync21 } from "node:fs";
248017
248027
  import { createServer as createServer4 } from "node:http";
248018
- import { join as join65, resolve as resolve40 } from "node:path";
248028
+ import { join as join66, resolve as resolve40 } from "node:path";
248019
248029
  var startPreview = async (dir, port) => {
248020
248030
  const root = resolve40(dir);
248021
- const fallback = existsSync60(join65(root, "404.html")) ? join65(root, "index.html") : null;
248031
+ const fallback = existsSync60(join66(root, "404.html")) ? join66(root, "index.html") : null;
248022
248032
  const server2 = createServer4((req, res) => {
248023
248033
  let path;
248024
248034
  try {
@@ -248034,9 +248044,9 @@ var startPreview = async (dir, port) => {
248034
248044
  res.end();
248035
248045
  return;
248036
248046
  }
248037
- let file = join65(root, ...parts);
248047
+ let file = join66(root, ...parts);
248038
248048
  if (existsSync60(file) && statSync21(file).isDirectory())
248039
- file = join65(file, "index.html");
248049
+ file = join66(file, "index.html");
248040
248050
  let status = 200;
248041
248051
  if (!existsSync60(file) || !statSync21(file).isFile()) {
248042
248052
  if (!fallback || /\.[a-z0-9]+$/i.test(parts[parts.length - 1] ?? "")) {
@@ -248070,12 +248080,12 @@ init_shared();
248070
248080
  // src/dev/https.ts
248071
248081
  import { existsSync as existsSync61, mkdirSync as mkdirSync37, readFileSync as readFileSync52, writeFileSync as writeFileSync39 } from "node:fs";
248072
248082
  import { homedir as homedir16 } from "node:os";
248073
- import { join as join66 } from "node:path";
248074
- var DIR = () => join66(homedir16(), ".lecodes", "dev-https");
248083
+ import { join as join67 } from "node:path";
248084
+ var DIR = () => join67(homedir16(), ".lecodes", "dev-https");
248075
248085
  var DAYS = 397;
248076
248086
  var RENEW_DAYS = 300;
248077
248087
  var devCertificate = async (names, dir = DIR()) => {
248078
- const files = { cert: join66(dir, "cert.pem"), key: join66(dir, "key.pem"), meta: join66(dir, "names.json") };
248088
+ const files = { cert: join67(dir, "cert.pem"), key: join67(dir, "key.pem"), meta: join67(dir, "names.json") };
248079
248089
  let kept = null;
248080
248090
  try {
248081
248091
  kept = JSON.parse(readFileSync52(files.meta, "utf8"));
@@ -248315,9 +248325,9 @@ var commandGroups = (opts) => [
248315
248325
  init_peers();
248316
248326
  init_env2();
248317
248327
  var STANDALONE2 = (() => {
248318
- const dir = dirname32(process.execPath);
248328
+ const dir = dirname33(process.execPath);
248319
248329
  const chisel = process.platform === "win32" ? "chisel.exe" : "chisel";
248320
- return existsSync63(join68(dir, "runtime")) && existsSync63(join68(dir, chisel));
248330
+ return existsSync63(join69(dir, "runtime")) && existsSync63(join69(dir, chisel));
248321
248331
  })();
248322
248332
  var INSTALLED = STANDALONE2 && (() => {
248323
248333
  const exe = process.platform === "win32" ? "lecodes.exe" : "lecodes";
@@ -248332,7 +248342,7 @@ var INSTALLED = STANDALONE2 && (() => {
248332
248342
  if (!d)
248333
248343
  return false;
248334
248344
  try {
248335
- const cand = join68(d, exe);
248345
+ const cand = join69(d, exe);
248336
248346
  return existsSync63(cand) && realpathSync5(cand) === self2;
248337
248347
  } catch {
248338
248348
  return false;