accelr8 3.1.0 → 3.2.0

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.
@@ -7,7 +7,7 @@ import {
7
7
  VERSION,
8
8
  decode,
9
9
  encode
10
- } from "./chunk-HF4HSRPK.js";
10
+ } from "./chunk-AY3UXM6A.js";
11
11
  import {
12
12
  DEFAULT_MODEL,
13
13
  addAccount,
@@ -1175,8 +1175,48 @@ function microLine(w, engine, frame2, info) {
1175
1175
 
1176
1176
  // src/voice.ts
1177
1177
  import { spawn, spawnSync } from "node:child_process";
1178
+ import fs2 from "node:fs";
1179
+ import path2 from "node:path";
1180
+
1181
+ // src/voicelog.ts
1178
1182
  import fs from "node:fs";
1183
+ import os from "node:os";
1179
1184
  import path from "node:path";
1185
+ var logPath = null;
1186
+ var enabled = true;
1187
+ function file() {
1188
+ if (!logPath) {
1189
+ const dir = path.join(os.homedir(), ".accelr8");
1190
+ try {
1191
+ fs.mkdirSync(dir, { recursive: true });
1192
+ } catch {
1193
+ }
1194
+ logPath = path.join(dir, "voice.log");
1195
+ }
1196
+ return logPath;
1197
+ }
1198
+ function stamp(nowMs) {
1199
+ const d = new Date(nowMs);
1200
+ const p = (n, w = 2) => String(n).padStart(w, "0");
1201
+ return `${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}.${p(d.getMilliseconds(), 3)}`;
1202
+ }
1203
+ function vlog(nowMs, stage, msg, data) {
1204
+ if (!enabled) return;
1205
+ try {
1206
+ const extra = data ? " " + Object.entries(data).map(([k, v]) => `${k}=${String(v).slice(0, 80)}`).join(" ") : "";
1207
+ fs.appendFileSync(file(), `${stamp(nowMs)} [${stage}] ${msg}${extra}
1208
+ `);
1209
+ } catch {
1210
+ }
1211
+ }
1212
+ function vlogSession(nowMs, header) {
1213
+ vlog(nowMs, "session", "\u2500\u2500\u2500\u2500 voice session \u2500\u2500\u2500\u2500", header);
1214
+ }
1215
+ function voiceLogPath() {
1216
+ return file();
1217
+ }
1218
+
1219
+ // src/voice.ts
1180
1220
  var SAMPLE_RATE = 16e3;
1181
1221
  var CHUNK_BYTES = 1280;
1182
1222
  var KILL_GRACE_MS = 300;
@@ -1235,13 +1275,13 @@ function detectVoiceTools() {
1235
1275
  }
1236
1276
  function which(bin) {
1237
1277
  const exts = process.platform === "win32" ? [".exe", ".cmd", ".bat", ""] : [""];
1238
- for (const dir of (process.env.PATH ?? "").split(path.delimiter).filter(Boolean)) {
1278
+ for (const dir of (process.env.PATH ?? "").split(path2.delimiter).filter(Boolean)) {
1239
1279
  for (const ext of exts) {
1240
- const candidate = path.join(dir, bin + ext);
1280
+ const candidate = path2.join(dir, bin + ext);
1241
1281
  try {
1242
- if (!fs.existsSync(candidate)) continue;
1243
- fs.accessSync(candidate, fs.constants.X_OK);
1244
- if (fs.statSync(candidate).isFile()) return candidate;
1282
+ if (!fs2.existsSync(candidate)) continue;
1283
+ fs2.accessSync(candidate, fs2.constants.X_OK);
1284
+ if (fs2.statSync(candidate).isFile()) return candidate;
1245
1285
  } catch {
1246
1286
  }
1247
1287
  }
@@ -1309,12 +1349,15 @@ var VoiceCapture = class {
1309
1349
  try {
1310
1350
  child = spawn(this.tools.ffmpegPath, args, { stdio: ["ignore", "pipe", "pipe"] });
1311
1351
  } catch (e) {
1352
+ vlog(Date.now(), "capture", "ffmpeg spawn threw", { backend, err: errMsg(e) });
1312
1353
  queueMicrotask(() => opts.onError("mic capture failed to start: " + errMsg(e)));
1313
1354
  return null;
1314
1355
  }
1356
+ vlog(Date.now(), "capture", "ffmpeg spawned", { backend, device: opts.device ?? "default", args: args.join(" ") });
1315
1357
  const s = { child, onChunk: opts.onChunk, buf: Buffer.alloc(0), stderrTail: "", produced: false, stopped: false };
1316
1358
  child.stdout?.on("data", (chunk) => {
1317
1359
  if (s.stopped) return;
1360
+ if (!s.produced) vlog(Date.now(), "capture", "first audio bytes from mic", { backend, bytes: chunk.length });
1318
1361
  s.produced = true;
1319
1362
  s.buf = s.buf.length ? Buffer.concat([s.buf, chunk]) : chunk;
1320
1363
  const whole = Math.floor(s.buf.length / CHUNK_BYTES) * CHUNK_BYTES;
@@ -1329,11 +1372,14 @@ var VoiceCapture = class {
1329
1372
  child.on("error", (e) => {
1330
1373
  if (s.stopped || this.session !== s) return;
1331
1374
  this.session = null;
1375
+ vlog(Date.now(), "capture", "ffmpeg error", { backend, code: e.code, produced: s.produced, stderr: s.stderrTail.trim() });
1332
1376
  opts.onError(e.code === "ENOENT" ? "ffmpeg not found" : "mic capture error: " + errMsg(e));
1333
1377
  });
1334
1378
  child.on("close", (code) => {
1335
1379
  if (s.stopped || this.session !== s) return;
1380
+ vlog(Date.now(), "capture", "ffmpeg exited", { backend, code, producedAudio: s.produced, stderr: s.stderrTail.trim() });
1336
1381
  if (backend === "primary" && process.platform === "linux" && !s.produced && code !== 0) {
1382
+ vlog(Date.now(), "capture", "alsa failed, retrying on pulse");
1337
1383
  const pulse = captureArgs("linux", opts.device).map((a) => a === "alsa" ? "pulse" : a);
1338
1384
  this.session = this.spawnSession(opts, pulse, "pulse");
1339
1385
  return;
@@ -1438,22 +1484,32 @@ var VoicePlayback = class {
1438
1484
  this.players.clear();
1439
1485
  }
1440
1486
  spawnPlayer(speakerId) {
1487
+ const args = playbackArgs(this.tools.ffplayPath);
1441
1488
  let child;
1442
1489
  try {
1443
- child = spawn(this.tools.ffplayPath, playbackArgs(this.tools.ffplayPath), { stdio: ["pipe", "ignore", "ignore"] });
1444
- } catch {
1490
+ child = spawn(this.tools.ffplayPath, args, { stdio: ["pipe", "ignore", "pipe"] });
1491
+ } catch (e) {
1492
+ vlog(Date.now(), "playback", "ffplay spawn threw", { speaker: speakerId, err: errMsg(e) });
1445
1493
  return null;
1446
1494
  }
1495
+ vlog(Date.now(), "playback", "ffplay spawned", { speaker: speakerId, args: args.join(" ") });
1447
1496
  const p = { child, alive: true, idleTimer: null, pre: [], flowing: false };
1497
+ let stderrTail = "";
1498
+ child.stderr?.setEncoding("utf8");
1499
+ child.stderr?.on("data", (c) => {
1500
+ stderrTail = (stderrTail + c).slice(-STDERR_TAIL);
1501
+ });
1448
1502
  child.stdin?.on("error", () => {
1449
1503
  p.alive = false;
1450
1504
  });
1451
- child.on("error", () => {
1505
+ child.on("error", (e) => {
1452
1506
  p.alive = false;
1507
+ vlog(Date.now(), "playback", "ffplay error", { speaker: speakerId, code: e.code, msg: errMsg(e) });
1453
1508
  if (this.players.get(speakerId) === p) this.reap(speakerId, p);
1454
1509
  });
1455
- child.on("close", () => {
1510
+ child.on("close", (code) => {
1456
1511
  p.alive = false;
1512
+ vlog(Date.now(), "playback", "ffplay exited", { speaker: speakerId, code, stderr: stderrTail.trim() });
1457
1513
  if (this.players.get(speakerId) === p) {
1458
1514
  if (p.idleTimer) {
1459
1515
  clearTimeout(p.idleTimer);
@@ -1547,60 +1603,19 @@ function errMsg(e) {
1547
1603
  return e instanceof Error ? e.message : String(e);
1548
1604
  }
1549
1605
 
1606
+ // src/world-data.ts
1607
+ var PACKED = `-92.32,48.24 -88.13,48.92 -83.11,46.27 -81.66,44.76 -82.09,42.29 -77.1,44.0 -69.95,46.92 -65.92,45.32 -66.37,44.25 -61.22,45.43 -64.94,47.34 -64.12,48.52 -70.68,47.02 -67.24,49.33 -59.82,50.48 -56.14,52.46 -59.07,53.58 -58.26,54.21 -60.69,55.33 -61.97,57.41 -64.35,59.49 -67.29,58.15 -69.89,59.91 -71.31,61.45 -78.22,61.97 -77.28,59.53 -77.09,55.88 -79.06,51.68 -82.23,52.7 -86.75,55.72 -92.17,56.86 -95.61,58.82 -92.66,62.02 -90.65,63.24 -95.96,64.12 -89.88,63.98 -89.3,65.22 -86.86,66.12 -84.54,66.88 -82.3,67.76 -83.1,69.68 -86.05,67.98 -88.18,68.2 -91.0,68.82 -91.72,69.69 -93.15,71.09 -96.58,71.05 -93.35,69.52 -94.23,68.25 -95.96,66.73 -98.83,68.27 -102.45,67.69 -108.34,68.43 -105.83,68.05 -108.15,66.6 -111.15,67.63 -114.1,68.23 -120.92,69.44 -124.32,69.26 -128.76,70.5 -131.86,69.19 -131.15,69.79 -135.81,69.13 -140.19,69.37 -141.2,69.58 -141.21,69.56 -142.49,69.83 -148.09,70.26 -154.37,70.96 -159.53,70.38 -166.64,68.25 -161.56,66.55 -162.99,65.97 -168.23,65.49 -161.12,64.49 -165.29,62.57 -164.58,60.06 -162.06,58.36 -157.85,58.12 -162.34,55.06 -156.52,57.11 -153.53,59.32 -149.18,60.81 -149.9,59.5 -146.54,60.36 -139.98,59.73 -137.12,58.28 -136.01,59.12 -133.84,57.12 -131.46,55.98 -132.08,57.2 -140.37,60.25 -141.21,60.16 -133.38,58.93 -130.88,54.83 -128.86,53.9 -126.58,52.12 -127.08,50.8 -124.42,49.66 -122.56,48.91 -122.44,48.92 -124.42,47.18 -124.52,42.48 -123.09,38.45 -121.73,36.62 -117.6,33.34 -117.28,32.64 -117.29,32.48 -114.75,27.8 -112.53,24.8 -110.55,24.07 -114.23,29.59 -112.58,29.99 -109.57,25.94 -105.61,21.94 -102.09,17.87 -95.75,15.94 -92.21,14.97 -92.22,14.71 -86.74,12.06 -83.03,8.65 -79.93,8.74 -77.0,7.82 -81.99,8.97 -83.92,12.7 -86.33,15.8 -88.4,15.92 -88.45,17.42 -87.01,21.33 -91.65,18.72 -96.96,20.37 -97.65,25.67 -97.62,25.82 -95.62,28.84 -90.77,29.03 -87.33,30.22 -82.69,28.15 -80.16,26.66 -80.74,32.31 -76.89,35.43 -76.47,38.21 -75.66,37.67 -71.31,41.76 -69.44,44.17 -67.69,47.03 -73.18,45.14 -79.26,43.28 -82.84,42.59 -83.49,45.32 -86.36,43.65 -87.75,43.42 -86.01,45.96 -87.0,46.59 -91.39,46.79 -90.05,47.96;-152.62,58.41 -152.6,58.4;-153.3,57.8 -152.4,57.48 -153.32,57.79;-166.96,53.96 -167.01,53.95;-168.36,53.5 -168.19,53.36;-170.73,52.68 -170.6,52.55;-174.47,51.94 -174.47,51.92;-176.58,51.71 -176.64,51.73;-177.55,51.76 -177.41,51.63;-178.27,51.75;177.35,51.8 177.33,51.76;172.44,53.0 172.55,53.03;-123.4,48.33 -128.0,50.84 -123.5,48.34;-132.49,52.88 -132.44,52.91;-132.64,53.02 -131.97,53.71 -132.63,53.02;-55.36,51.56 -54.66,49.52 -53.65,47.48 -52.98,46.31 -56.12,46.84 -58.47,47.57 -57.61,50.38 -55.39,51.53;-61.37,49.01 -61.8,49.29 -61.38,49.03;-63.01,46.71 -64.42,46.61 -63.04,46.68;-60.14,46.48 -60.14,46.5;-71.97,41.11 -71.97,41.15;-80.79,27.03 -81.01,26.99;-113.01,42.09 -113.1,42.01;-155.74,20.02 -155.73,19.98;-156.51,20.78 -156.51,20.78;-157.12,21.21 -157.08,20.95;-157.87,21.42;-159.53,22.07;-117.44,66.46 -119.59,65.24 -123.95,65.03 -123.69,66.44 -119.21,66.22 -117.44,66.44;-120.71,64.03 -114.91,62.3 -109.07,62.72 -112.62,61.19 -118.68,61.19 -117.01,61.17 -115.97,62.56 -119.46,64.0 -120.59,63.94;-112.31,58.46 -108.9,59.44 -104.14,58.9 -102.56,56.72 -101.82,58.73 -104.65,58.91 -111.0,58.51 -112.35,58.62;-98.74,50.09 -99.75,52.24 -99.62,51.47 -98.82,50.39;-97.02,50.21 -97.5,54.02 -98.69,52.93 -97.19,51.09 -96.98,50.2;-95.34,49.04 -92.32,50.34 -94.14,49.47 -95.36,48.82;-80.39,56.16 -79.22,55.94 -80.34,56.08;-103.56,58.6 -103.6,58.58;-101.82,58.03 -102.33,58.1 -101.77,58.06;-101.88,55.79 -97.92,57.15 -101.22,55.85 -101.88,55.74;-77.61,6.8 -78.7,0.97 -80.75,-4.47 -76.19,-14.57 -70.44,-18.75 -70.68,-26.15 -71.44,-32.03 -73.38,-37.27 -73.06,-42.11 -73.17,-46.09 -73.52,-48.05 -73.67,-51.56 -71.06,-53.88 -69.14,-50.77 -67.51,-46.59 -63.49,-42.8 -62.14,-40.16 -57.12,-36.71 -53.17,-34.15 -51.26,-32.02 -48.16,-25.48 -40.73,-22.32 -38.88,-15.24 -34.6,-7.81 -41.95,-3.42 -48.02,-1.84 -48.44,-1.57 -50.81,0.0 -54.47,5.39 -60.59,8.32 -64.19,9.88 -70.78,10.64 -70.97,11.89 -76.26,8.76 -77.61,6.8;-69.14,-52.79 -66.16,-55.08 -70.01,-54.88 -70.55,-53.85 -69.31,-52.81;-59.29,-51.58 -59.35,-51.54;-58.65,-51.55 -58.55,-51.56;-84.39,21.44 -73.9,19.73 -79.27,21.18 -83.74,21.8 -84.32,21.42;-66.96,17.95 -67.05,17.89;-77.88,17.22 -78.06,16.98;-74.47,18.08 -69.88,18.99 -71.1,17.76 -74.45,17.86;-85.28,73.74 -85.79,70.96 -85.13,71.94 -84.74,72.96 -80.61,73.1 -78.45,72.2 -75.44,72.55 -73.89,71.98 -72.56,71.04 -71.49,70.57 -69.78,70.29 -68.12,69.71 -65.91,69.19 -66.92,68.39 -64.08,67.68 -62.5,66.68 -63.07,65.33 -66.11,66.08 -67.48,65.41 -64.05,63.15 -66.58,63.26 -69.04,62.33 -72.22,63.77 -76.88,64.17 -73.25,65.54 -70.09,66.64 -72.05,67.44 -76.32,68.36 -78.34,70.17 -82.12,69.71 -87.64,70.12 -89.68,71.43 -85.28,73.74;-80.9,76.1 -84.21,76.28 -88.94,76.38 -85.47,77.4 -85.43,77.93 -87.01,78.54 -83.17,78.94 -84.87,79.93 -81.33,79.82 -76.27,80.92 -82.88,80.62 -82.58,81.16 -86.51,81.05 -89.36,81.21 -90.45,81.38 -89.28,81.86 -87.21,82.3 -80.51,82.05 -80.16,82.55 -77.83,82.86 -75.51,83.05 -71.18,82.9 -65.1,82.78 -63.34,81.8 -68.26,81.26 -69.46,80.34 -71.05,79.82 -74.4,79.46 -75.42,79.03 -75.48,78.92 -76.01,78.2 -80.66,77.28 -78.07,76.98 -80.9,76.13;-92.86,74.13 -92.5,72.7 -94.89,73.16 -92.96,74.14;-94.8,76.95 -89.68,76.04 -88.52,75.4 -82.36,75.67 -79.39,74.65 -86.15,74.22 -91.7,74.94 -95.6,76.91 -94.87,76.96;-99.96,73.74 -97.89,72.9 -98.28,71.13 -102.04,72.92 -101.34,73.14 -99.69,73.59;-107.58,73.25 -104.59,71.02 -101.71,69.56 -104.07,68.62 -106.61,69.12 -114.09,69.05 -113.89,70.12 -115.88,70.32 -116.1,71.32 -117.45,72.48 -113.53,72.44 -109.84,72.24 -106.62,71.71 -107.43,73.04;-120.96,74.29 -118.37,72.53 -123.06,71.18 -123.4,73.77 -120.93,74.27;-108.83,76.74 -106.25,75.54 -107.08,74.78 -112.99,74.16 -112.28,74.99 -116.04,75.33 -115.27,76.2 -110.95,75.56 -109.77,76.31 -108.82,76.7;-115.7,77.46 -118.1,76.3 -121.13,76.37 -116.04,77.28;-110.01,77.86 -112.36,77.68 -109.96,77.86;-109.6,78.48 -112.2,78.01 -109.6,78.48;-97.87,76.61 -99.21,75.31 -100.86,75.6 -99.4,76.26 -97.79,76.6;-94.72,75.53 -94.66,75.52;-104.1,79.01 -99.19,77.54 -103.22,78.08 -104.3,78.95;-93.74,77.52 -93.74,77.52;-96.88,78.5 -96.91,77.77 -96.94,78.48;-84.69,65.84 -81.58,63.87 -85.0,62.96 -84.63,65.71;-81.84,62.75 -82.01,62.63;-79.88,62.12 -79.88,62.12;-43.53,59.89 -45.29,60.67 -47.91,60.83 -49.9,62.41 -50.71,64.42 -51.39,64.94 -52.96,66.09 -53.62,67.19 -53.51,67.51 -51.84,68.65 -52.19,70.0 -51.85,71.03 -55.41,71.41 -54.63,72.97 -56.98,74.7 -61.95,76.09 -66.38,75.83 -71.13,77.0 -66.81,77.6 -70.78,77.78 -64.96,79.7 -63.38,81.16 -56.89,82.17 -48.18,82.15 -42.08,82.74 -38.02,83.54 -23.96,82.94 -25.97,81.97 -25.99,80.64 -13.57,80.97 -16.6,80.16 -19.82,78.82 -18.8,77.54 -21.98,76.46 -20.69,75.12 -21.78,74.4 -24.1,73.69 -26.54,73.08 -24.63,72.69 -21.84,71.69 -24.62,71.24 -27.16,70.89 -27.21,70.0 -24.1,69.35 -28.35,68.43 -32.48,68.56 -35.26,66.26 -37.9,65.9 -40.04,65.0 -40.49,64.04 -42.01,63.14 -42.88,61.15 -43.09,60.07 -43.56,59.9;-16.26,66.41 -15.32,64.29 -20.14,63.47 -21.76,64.21 -21.33,64.97 -23.04,65.62 -21.76,66.26 -18.77,66.12 -16.23,66.35;0.56,51.47 -1.71,54.94 -3.41,57.52 -5.42,58.14 -5.77,55.59 -3.48,54.82 -4.68,52.88 -2.68,51.58 -3.8,50.08 1.26,51.14 0.65,51.41;-7.17,54.91 -9.97,53.47 -8.52,51.76 -5.69,54.79 -7.34,55.25;-1.33,60.66 -1.17,60.38;-6.18,58.44 -6.09,58.36;-6.47,57.58 -6.33,57.54;-7.3,57.54;-7.46,57.05;-6.54,56.94;-6.0,55.94;-5.09,55.55;-4.44,54.38 -4.3,54.19;-8.08,71.02 -8.21,70.86;16.92,79.52 22.26,78.46 16.86,76.41 16.0,77.39 16.03,77.92 16.81,79.5;14.71,79.4 16.05,79.12 14.02,77.8 13.56,78.46 12.63,79.26 14.68,79.4;22.01,78.24 21.86,78.23;21.54,77.75 23.88,77.26 21.53,77.67 22.79,77.79;23.5,79.97 28.24,79.54 20.85,78.94 19.0,79.34 21.05,79.88 23.41,79.96;46.98,80.23 43.13,79.97 47.18,80.22;50.43,80.19 50.55,79.88 47.77,79.86 50.45,80.14;61.79,80.18 61.79,80.18;65.08,80.69 64.27,80.59 65.13,80.68;-5.13,35.66 4.06,36.63 10.4,37.12 11.36,33.61 20.1,30.1 23.49,32.17 31.65,30.8 35.76,23.74 39.75,14.82 42.93,11.34 51.52,11.45 49.82,6.99 43.13,-0.62 39.15,-7.58 40.37,-13.2 37.74,-18.17 35.33,-22.71 32.84,-28.15 26.5,-34.39 19.55,-35.51 17.5,-30.88 12.24,-18.75 13.89,-12.81 12.05,-5.55 9.67,0.14 7.19,3.79 1.74,5.39 -4.77,4.59 -12.0,6.75 -15.54,10.98 -16.33,15.5 -16.1,22.29 -12.9,27.12 -9.52,31.09 -5.41,35.58;33.71,0.0 33.48,-3.42 33.34,-0.2 33.71,0.0;49.3,-12.5 49.28,-18.79 43.95,-25.5 44.37,-20.08 46.34,-16.31 47.91,-14.08 49.3,-12.5;178.88,69.1 181.2,68.42 183.52,67.78 188.87,66.38 186.54,64.74 182.87,65.63 180.13,65.14 179.48,64.88 178.2,64.29 177.46,62.62 170.42,60.17 164.48,59.89 162.92,57.34 161.82,54.88 156.42,51.09 156.4,57.76 163.79,61.73 159.9,60.73 156.81,61.68 153.83,59.1 148.57,59.46 140.77,58.39 137.1,54.07 140.72,52.43 138.77,47.3 129.92,42.04 128.33,38.46 126.15,35.18 125.12,39.08 121.62,40.15 117.58,38.21 121.77,36.9 120.73,32.65 121.28,30.25 118.83,24.93 112.69,21.81 108.53,21.73 107.55,16.34 107.32,10.45 104.39,10.37 100.01,13.52 100.26,8.3 103.22,1.56 98.21,9.17 97.66,15.36 94.21,17.79 90.05,21.74 90.06,21.03 82.06,15.95 80.05,11.72 76.41,8.6 72.79,17.43 72.02,20.0 68.98,21.99 64.62,24.41 57.83,24.77 53.11,26.2 49.67,29.41 50.96,25.15 54.33,23.44 59.03,22.57 57.87,18.86 52.95,15.74 47.26,12.96 42.75,14.68 39.93,19.61 36.92,25.78 33.3,28.46 32.6,30.63 32.18,30.58 36.08,35.03 32.53,36.17 27.77,36.94 26.51,39.18 31.54,40.82 38.53,40.48 40.35,43.17 39.88,46.45 35.18,44.99 33.5,44.96 30.24,45.14 28.7,41.48 26.55,39.84 23.62,39.67 23.8,37.34 21.9,36.92 18.79,42.02 14.52,44.31 14.58,42.25 18.32,39.57 16.05,39.35 11.52,42.36 6.87,43.08 2.8,41.09 -1.11,37.14 -6.24,36.7 -8.67,39.57 -6.51,43.13 -0.84,45.55 -3.93,48.4 0.48,49.09 4.2,51.29 6.44,52.92 8.42,55.94 11.72,55.49 11.73,53.66 16.78,54.14 21.4,56.32 24.67,57.2 28.94,59.18 24.16,59.52 22.07,62.66 23.76,65.35 18.7,62.54 19.11,59.67 18.4,58.54 15.34,55.73 11.74,58.08 8.37,57.68 5.8,59.2 7.38,60.86 7.51,61.86 9.62,62.99 13.37,65.46 15.46,67.12 18.54,68.62 22.32,69.64 24.77,70.17 25.93,69.79 28.56,70.46 29.75,69.76 33.83,69.11 41.9,66.85 35.14,66.25 33.3,66.07 35.46,64.15 37.68,64.03 41.71,64.09 44.8,65.58 44.87,68.16 45.92,66.83 51.79,67.85 53.7,67.89 59.68,68.09 65.07,69.08 68.56,69.19 68.38,70.97 73.03,71.62 73.8,68.29 69.42,66.45 73.43,66.36 77.51,68.36 80.74,66.74 75.27,68.67 75.11,71.8 78.62,70.56 78.43,71.9 82.72,71.23 84.25,70.03 81.4,72.76 86.5,74.01 87.68,74.78 90.25,75.23 89.68,75.57 95.12,75.95 99.69,76.09 104.1,77.52 106.34,76.4 112.99,75.6 107.88,73.72 110.43,73.71 113.34,73.37 123.1,73.28 128.94,73.02 126.1,72.24 130.53,70.86 135.49,71.51 139.6,72.23 146.04,72.39 146.92,72.21 150.77,71.28 159.92,70.14 167.68,69.63 170.2,69.99 178.88,69.1;68.33,76.71 66.03,75.62 59.1,74.11 54.92,73.03 56.67,74.1 58.56,75.09 63.86,75.87 68.19,76.7;53.04,72.57 58.29,70.39 55.03,70.78 53.44,72.26 53.63,72.61;52.22,46.5 51.73,44.73 52.56,41.8 53.43,40.4 54.22,37.86 49.04,38.45 48.17,42.76 49.33,45.64 52.22,46.5;62.32,46.32 60.32,43.06 59.57,45.58 61.94,46.33;79.55,46.12 74.3,44.44 78.62,45.79 79.66,46.07;76.81,41.96 76.73,41.86;35.15,35.15 34.61,34.84 35.18,35.17;23.84,35.33 24.3,34.91 24.09,35.39;15.54,37.89 13.47,37.89 15.54,37.89;9.56,40.95 8.46,39.99 9.12,40.69;9.72,42.6 9.54,42.35;80.6,8.95 79.73,5.96 80.1,8.3;11.04,57.44 10.67,57.25;-77.92,24.67 -77.98,24.22;-77.61,23.62 -77.18,23.64;-75.55,24.13 -75.41,24.31;-91.4,-0.17 -91.52,-0.26;-60.25,46.68 -60.71,46.33;-63.89,49.47 -63.45,49.43;142.53,-10.6 145.62,-16.34 149.79,-22.09 153.21,-26.82 150.52,-35.19 145.6,-38.53 140.13,-37.69 137.34,-34.77 135.76,-34.56 131.5,-31.34 121.72,-33.65 115.62,-33.25 114.09,-26.01 114.88,-21.27 122.34,-18.13 125.32,-14.53 128.39,-14.9 132.35,-11.42 136.16,-12.43 138.07,-16.45 142.25,-10.78;144.72,-40.68 148.32,-42.14 145.57,-42.77 146.47,-41.19;172.86,-34.23 176.1,-37.52 177.06,-39.49 174.77,-38.03 172.83,-34.27;172.36,-40.53 172.92,-43.81 168.41,-46.13 170.26,-43.21 173.69,-40.94;150.74,-10.18 143.04,-8.26 138.48,-6.97 131.95,-2.94 130.91,-1.35 134.38,-2.64 141.24,-2.62 148.19,-8.15 150.75,-10.27;117.24,7.01 117.9,0.76 113.89,-3.5 109.44,-0.82 113.13,3.38 117.24,7.01;95.31,5.75 102.32,1.4 106.03,-2.98 101.46,-2.81 95.2,5.73;140.91,41.53 140.79,35.75 136.82,34.56 133.56,34.72 132.49,35.41 136.73,37.2 139.82,40.0 140.68,41.43;133.71,34.3 131.41,31.58 129.38,33.1 133.9,34.37;141.89,45.5 144.12,42.92 140.3,41.64 141.53,45.3 141.89,45.53;142.57,54.36 143.64,49.19 141.99,45.88 141.92,50.85 142.6,54.34;121.92,25.48 120.53,24.7 121.7,25.51;110.81,20.07 109.2,19.66 110.81,20.07;106.51,-6.16 114.15,-7.72 108.71,-7.89 106.51,-6.16;164.27,-20.01 164.16,-20.27;178.61,-17.04 178.61,-17.04;179.45,-16.43 179.35,-16.43;-172.55,-13.39 -172.61,-13.78;122.26,18.67 123.05,13.86 120.73,13.8 120.43,16.43 121.72,18.4;125.34,9.79 125.56,6.28 122.38,7.0 125.1,9.38;119.64,11.35 118.81,10.16 119.59,10.86 119.64,11.35;-179.87,65.14 -177.13,65.63 -173.46,64.74 -171.13,66.38 -176.48,67.78 -178.8,68.42;101.96,79.08 101.31,77.86 101.22,79.04;94.29,79.29 95.31,78.68 100.02,79.43 97.26,79.62 95.44,79.65;95.46,80.62 92.39,79.66 95.07,80.54;138.54,76.05 144.93,75.45 140.3,74.99 137.27,75.44 138.29,75.98;146.08,75.29 147.75,74.73 145.85,75.06;141.44,73.88 141.48,73.84;0.01,-71.68 6.57,-70.57 15.04,-70.44 25.1,-70.75 33.37,-69.1 38.46,-69.77 42.85,-68.16 46.59,-67.23 49.35,-66.96 52.9,-65.97 58.46,-67.2 63.6,-67.58 70.63,-68.41 69.24,-70.36 76.2,-69.44 88.08,-66.64 94.98,-66.52 101.53,-66.09 111.31,-65.91 118.64,-66.87 126.24,-66.24 133.09,-66.18 139.85,-66.72 146.86,-67.96 153.65,-68.82 159.94,-69.57 164.1,-70.67 170.19,-71.94 165.68,-74.64 163.82,-77.6 162.1,-78.95 166.72,-82.84 175.58,-83.86;-178.56,-84.37 -147.96,-85.4 -152.96,-81.12 -153.95,-79.5 -151.24,-77.48 -146.74,-76.44 -137.68,-75.16 -131.63,-74.63 -123.05,-74.41 -114.76,-73.97 -111.91,-75.41 -105.05,-74.77 -100.9,-74.21 -101.04,-73.18 -100.28,-73.06 -93.06,-73.33 -85.4,-73.18 -79.82,-73.04 -78.21,-72.52 -71.9,-73.41 -67.51,-71.1 -67.57,-68.92 -66.65,-66.83 -64.3,-65.28 -59.14,-63.74 -59.58,-64.37 -62.5,-65.94 -62.48,-66.66 -65.64,-68.02 -63.85,-69.07 -61.69,-70.87 -60.89,-72.71 -61.07,-74.3 -63.33,-75.88 -76.05,-77.06 -83.04,-77.12 -74.3,-80.83 -56.4,-82.14 -42.46,-81.65 -31.6,-80.17 -34.01,-79.2 -32.48,-77.28 -26.28,-76.18 -17.18,-73.45 -11.2,-72.01 -8.67,-71.98 -5.45,-71.45 -0.82,-71.74 0.07,-71.68;164.65,-77.89 170.95,-77.37 179.67,-78.25;-178.74,-78.24 -165.76,-78.47 -158.42,-77.73;-58.98,-64.63 -60.99,-68.62 -61.02,-71.7;-62.01,-74.94 -52.0,-77.07 -42.23,-77.8 -36.22,-78.03;-35.03,-77.81 -26.13,-75.54 -19.35,-73.04 -12.16,-71.86 -6.15,-70.65 -0.57,-69.14 4.93,-70.25 10.91,-69.99 16.52,-69.87 25.41,-70.22 32.13,-69.29 33.62,-69.58;70.56,-68.53 73.91,-69.51;81.42,-67.87 84.67,-66.41 89.07,-66.73;-135.79,-74.67 -124.34,-73.22 -116.65,-74.08 -109.93,-74.64 -105.36,-74.56 -105.83,-74.77;-69.3,-70.06 -71.33,-72.68 -71.42,-71.85 -75.1,-71.46 -71.79,-70.55 -70.34,-69.26 -69.34,-70.13;-49.2,-77.83 -44.59,-78.79 -44.14,-80.13 -59.04,-79.95 -49.28,-77.84 -48.24,-77.81;-58.13,-80.12 -63.25,-80.2 -58.32,-80.12;-163.64,-78.74 -161.2,-79.93 -163.62,-78.74;66.82,66.82 66.82,66.82`;
1608
+ var POLYLINES = PACKED.split(";").map(
1609
+ (pl) => pl.split(" ").filter(Boolean).map((pt) => {
1610
+ const c = pt.split(",");
1611
+ return [parseFloat(c[0]), parseFloat(c[1])];
1612
+ }).filter((p) => Number.isFinite(p[0]) && Number.isFinite(p[1]))
1613
+ ).filter((pl) => pl.length > 0);
1614
+
1550
1615
  // src/map.ts
1551
1616
  var LAND = 240;
1552
1617
  var MIXED = 231;
1553
- var LAND_CHAR = "\xB7";
1554
1618
  var DOT_CHAR = "\u25CF";
1555
- var WORLD = [
1556
- " ### ",
1557
- // 90..81N arctic
1558
- " ##### ###### ########### ",
1559
- // 81..72N archipelago·Greenland·Siberia
1560
- " ################# ###### # #### ####################### ",
1561
- // 72..63N Alaska·Canada·Iceland·Scandinavia·Russia
1562
- " ############ #### ## # ########################### ",
1563
- // 63..54N Hudson Bay notch·Scotland·Baltic·Kamchatka
1564
- " ############## ## ####################### ",
1565
- // 54..45N US/Canada border·UK·Europe·steppe
1566
- " ########## ### ###### ############# # ",
1567
- // 45..36N US·Iberia·Med·central Asia·Japan
1568
- " ######## ####################### ## ",
1569
- // 36..27N south US·north Africa·Middle East·China
1570
- " #### ## ######### ### ### ###### ",
1571
- // 27..18N Mexico·Cuba·Sahara·Arabia·India·SE Asia
1572
- " ### ## ############ ## ### # ",
1573
- // 18..9N Cent. America·Sahel·Horn·Philippines
1574
- " ##### ########### # ##### ",
1575
- // 9..0N Colombia·Congo·Sri Lanka·Indonesia
1576
- " ######## ####### ### #### ",
1577
- // 0..9S Amazon·Tanzania·Java·New Guinea
1578
- " ####### ##### # ##### ",
1579
- // 9..18S Brazil·Angola·Madagascar·north Australia
1580
- " ###### #### # ######## ",
1581
- // 18..27S Paraguay·Namibia·Australia
1582
- " #### ### ####### ",
1583
- // 27..36S Argentina·South Africa·Sydney coast
1584
- " ### # ## ",
1585
- // 36..45S Patagonia·Tasmania·New Zealand
1586
- " ## # ",
1587
- // 45..54S
1588
- " # ",
1589
- // 54..63S Tierra del Fuego
1590
- " ## ###### ####### ",
1591
- // 63..72S Antarctic peninsula + coast
1592
- " ######################################### ",
1593
- // 72..81S Antarctica
1594
- " ############################### "
1595
- // 81..90S
1596
- ];
1597
- var WORLD_W = 60;
1598
- var WORLD_H = 20;
1599
- function landAt(x, y, W2, H2) {
1600
- const bx = Math.min(WORLD_W - 1, Math.floor((x + 0.5) * WORLD_W / W2));
1601
- const by = Math.min(WORLD_H - 1, Math.floor((y + 0.5) * WORLD_H / H2));
1602
- return WORLD[by]?.charCodeAt(bx) === 35;
1603
- }
1604
1619
  function project(lat, lon, w, h) {
1605
1620
  const la = Math.max(-90, Math.min(90, Number.isFinite(lat) ? lat : 0));
1606
1621
  const lo = Math.max(-180, Math.min(180, Number.isFinite(lon) ? lon : 0));
@@ -1608,6 +1623,58 @@ function project(lat, lon, w, h) {
1608
1623
  const y = h > 1 ? Math.round((90 - la) / 180 * (h - 1)) : 0;
1609
1624
  return { x, y };
1610
1625
  }
1626
+ var BRAILLE = [[1, 8], [2, 16], [4, 32], [64, 128]];
1627
+ var brailleCache = null;
1628
+ function brailleWorld(W2, H2) {
1629
+ if (brailleCache && brailleCache.w === W2 && brailleCache.h === H2) return brailleCache.grid;
1630
+ const pw = W2 * 2, ph = H2 * 4;
1631
+ const grid2 = new Uint8Array(W2 * H2);
1632
+ const toX = (lon) => {
1633
+ let l = lon;
1634
+ if (l > 180) l -= 360;
1635
+ if (l < -180) l += 360;
1636
+ return Math.round((l + 180) / 360 * (pw - 1));
1637
+ };
1638
+ const toY = (lat) => Math.round((90 - Math.max(-90, Math.min(90, lat))) / 180 * (ph - 1));
1639
+ const set = (x, y) => {
1640
+ if (x < 0 || x >= pw || y < 0 || y >= ph) return;
1641
+ grid2[(y >> 2) * W2 + (x >> 1)] |= BRAILLE[y & 3][x & 1];
1642
+ };
1643
+ const line = (x0, y0, x1, y1) => {
1644
+ const dx = Math.abs(x1 - x0), dy = Math.abs(y1 - y0), sx = x0 < x1 ? 1 : -1, sy = y0 < y1 ? 1 : -1;
1645
+ let err = dx - dy, guard = 0;
1646
+ for (; ; ) {
1647
+ set(x0, y0);
1648
+ if (x0 === x1 && y0 === y1 || guard++ > pw + ph) break;
1649
+ const e2 = 2 * err;
1650
+ if (e2 > -dy) {
1651
+ err -= dy;
1652
+ x0 += sx;
1653
+ }
1654
+ if (e2 < dx) {
1655
+ err += dx;
1656
+ y0 += sy;
1657
+ }
1658
+ }
1659
+ };
1660
+ for (const pl of POLYLINES) {
1661
+ if (pl.length === 1) {
1662
+ set(toX(pl[0][0]), toY(pl[0][1]));
1663
+ continue;
1664
+ }
1665
+ for (let i = 1; i < pl.length; i++) {
1666
+ const ax = toX(pl[i - 1][0]), ay = toY(pl[i - 1][1]), bx = toX(pl[i][0]), by = toY(pl[i][1]);
1667
+ if (Math.abs(ax - bx) > pw * 0.6) {
1668
+ set(ax, ay);
1669
+ set(bx, by);
1670
+ continue;
1671
+ }
1672
+ line(ax, ay, bx, by);
1673
+ }
1674
+ }
1675
+ brailleCache = { w: W2, h: H2, grid: grid2 };
1676
+ return grid2;
1677
+ }
1611
1678
  function renderMap(w, h, dots) {
1612
1679
  const W2 = Math.max(0, Math.floor(w));
1613
1680
  const H2 = Math.max(0, Math.floor(h));
@@ -1637,13 +1704,15 @@ function renderMap(w, h, dots) {
1637
1704
  if (row) row.push(hit);
1638
1705
  else hitRows.set(hit.y, [hit]);
1639
1706
  }
1707
+ const grid2 = brailleWorld(W2, H2);
1640
1708
  for (let y = 0; y < H2; y++) {
1641
1709
  const chars = new Array(W2).fill(" ");
1642
1710
  const colors = new Array(W2).fill(-1);
1643
1711
  const isDot = new Array(W2).fill(false);
1644
1712
  for (let x = 0; x < W2; x++) {
1645
- if (landAt(x, y, W2, H2)) {
1646
- chars[x] = LAND_CHAR;
1713
+ const b = grid2[y * W2 + x];
1714
+ if (b) {
1715
+ chars[x] = String.fromCharCode(10240 + b);
1647
1716
  colors[x] = LAND;
1648
1717
  }
1649
1718
  }
@@ -1924,6 +1993,8 @@ var voiceCapture = null;
1924
1993
  var voicePlayback = null;
1925
1994
  var voiceDevice = process.env.ACCELR8_MIC || void 0;
1926
1995
  var voiceRetries = 0;
1996
+ var voiceSent = 0;
1997
+ var voiceRecv = /* @__PURE__ */ new Map();
1927
1998
  function autoPickMic() {
1928
1999
  if (process.platform === "darwin") {
1929
2000
  const mics = listMicDevices();
@@ -1945,7 +2016,11 @@ function startCapture() {
1945
2016
  device: voiceDevice,
1946
2017
  onChunk: (b64) => {
1947
2018
  voiceRetries = 0;
1948
- if (voiceTransmit) sendMsg({ t: "voiceFrame", data: b64 });
2019
+ if (!voiceTransmit) return;
2020
+ voiceSent++;
2021
+ if (voiceSent === 1) vlog(Date.now(), "transmit", "first frame sent to server");
2022
+ else if (voiceSent % 125 === 0) vlog(Date.now(), "transmit", "still sending", { frames: voiceSent });
2023
+ sendMsg({ t: "voiceFrame", data: b64 });
1949
2024
  },
1950
2025
  onError: (m) => {
1951
2026
  if (!voiceTransmit) return;
@@ -1978,12 +2053,25 @@ function toggleVoice() {
1978
2053
  voiceCapture = new VoiceCapture(voiceTools);
1979
2054
  voiceOn = true;
1980
2055
  voiceTransmit = false;
2056
+ voiceSent = 0;
2057
+ voiceRecv.clear();
1981
2058
  if (voiceDevice === void 0 && voiceTools.capture) voiceDevice = autoPickMic();
2059
+ vlogSession(Date.now(), {
2060
+ platform: process.platform,
2061
+ version: PROTO,
2062
+ name: me.name,
2063
+ ffmpeg: voiceTools.ffmpegPath ?? "MISSING",
2064
+ ffplay: voiceTools.ffplayPath ?? "MISSING",
2065
+ capture: voiceTools.capture,
2066
+ playback: voiceTools.playback,
2067
+ mic: voiceDevice ?? "default"
2068
+ });
1982
2069
  sendMsg({ t: "voiceJoin" });
1983
2070
  state.status = voiceTools.capture ? "voice on \xB7 /talk (or ctrl-g) to speak" : "voice on \xB7 listen only (no mic found)";
1984
2071
  }
1985
2072
  function leaveVoice() {
1986
2073
  if (!voiceOn) return;
2074
+ vlog(Date.now(), "session", "leaving voice", { sent: voiceSent, recvSpeakers: voiceRecv.size, recvTotal: [...voiceRecv.values()].reduce((a, b) => a + b, 0) });
1987
2075
  voiceCapture?.stop();
1988
2076
  voicePlayback?.stopAll();
1989
2077
  voiceCapture = null;
@@ -2439,7 +2527,12 @@ function handleServer(msg) {
2439
2527
  state.voicePeers = Array.isArray(msg.peers) ? msg.peers : [];
2440
2528
  break;
2441
2529
  case "voiceFrame":
2442
- if (voiceOn) voicePlayback?.feed(msg.sid, msg.data);
2530
+ if (voiceOn) {
2531
+ const n = (voiceRecv.get(msg.sid) ?? 0) + 1;
2532
+ voiceRecv.set(msg.sid, n);
2533
+ if (n === 1) vlog(Date.now(), "receive", "first frame received from a peer", { sid: msg.sid.slice(0, 8) });
2534
+ voicePlayback?.feed(msg.sid, msg.data);
2535
+ }
2443
2536
  break;
2444
2537
  case "error": {
2445
2538
  if (msg.code === "chatRate" || msg.code === "msgTooLarge") {
@@ -3246,8 +3339,9 @@ function mapDotsFromSessions() {
3246
3339
  }
3247
3340
  var teamMap = null;
3248
3341
  function blitMapLine(x0, y, line) {
3249
- puts(x0, y, line.text, { color: C.rule, bgColor: C.bg });
3342
+ puts(x0, y, line.text, { color: readableFg(C.rule, C.bg, 3.05), bgColor: C.bg });
3250
3343
  for (const sp of line.spans) {
3344
+ if (!sp.bold) continue;
3251
3345
  const seg = [...line.text].slice(sp.start, sp.end).join("");
3252
3346
  if (seg) puts(x0 + sp.start, y, seg, { color: readableFg(sp.color, C.bg, 2.6), bold: true, bgColor: C.bg });
3253
3347
  }
@@ -3933,6 +4027,17 @@ function slashCommand(text) {
3933
4027
  toggleVoice();
3934
4028
  } else if (cmd === "/talk" || cmd === "/mute") {
3935
4029
  toggleTalk();
4030
+ } else if (cmd === "/voice debug") {
4031
+ const recvTotal = [...voiceRecv.values()].reduce((a, b) => a + b, 0);
4032
+ sidecarBlock = { title: "voice debug", at: Date.now(), lines: [
4033
+ `on: ${voiceOn} \xB7 live: ${voiceTransmit}`,
4034
+ `tools: ffmpeg ${voiceTools?.ffmpegPath ? "ok" : "MISSING"} \xB7 ffplay ${voiceTools?.ffplayPath ? "ok" : "MISSING"}`,
4035
+ `mic: ${voiceDevice ?? "default"} \xB7 peers: ${state.voicePeers.length}`,
4036
+ `sent: ${voiceSent} \xB7 received: ${recvTotal} from ${voiceRecv.size}`,
4037
+ `log: ${voiceLogPath()}`,
4038
+ "send me that file if voice fails"
4039
+ ] };
4040
+ state.status = "voice debug \xB7 see the panel \xB7 log at ~/.accelr8/voice.log";
3936
4041
  } else if (cmd === "/voice mics" || cmd === "/mics") {
3937
4042
  const mics = listMicDevices();
3938
4043
  sidecarBlock = { title: "microphones", at: Date.now(), lines: mics.length ? mics.map((m) => `${m.index} ${m.name}${voiceDevice === m.index ? " \xB7 selected" : ""}`).concat("use: /voice mic <index>") : ["none found (need ffmpeg)"] };