apex-dev 3.8.0 → 3.10.3

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.
Files changed (2) hide show
  1. package/dist/index.js +414 -720
  2. package/package.json +4 -3
package/dist/index.js CHANGED
@@ -29,8 +29,8 @@ var __export = (target, all) => {
29
29
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
30
30
  var __require = import.meta.require;
31
31
 
32
- // node_modules/@opentui/react/chunk-eecw9x2f.js
33
- var init_chunk_eecw9x2f = () => {};
32
+ // node_modules/@opentui/react/chunk-2mx7fq49.js
33
+ var init_chunk_2mx7fq49 = () => {};
34
34
 
35
35
  // node_modules/react/cjs/react.production.js
36
36
  var exports_react_production = {};
@@ -24044,11 +24044,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
24044
24044
  });
24045
24045
  });
24046
24046
 
24047
- // node_modules/@opentui/react/chunk-pm1hna8x.js
24048
- var exports_chunk_pm1hna8x = {};
24047
+ // node_modules/@opentui/react/chunk-bdqvmfwv.js
24048
+ var exports_chunk_bdqvmfwv = {};
24049
24049
  var import_react_devtools_core, g;
24050
- var init_chunk_pm1hna8x = __esm(async () => {
24051
- init_chunk_eecw9x2f();
24050
+ var init_chunk_bdqvmfwv = __esm(async () => {
24051
+ init_chunk_2mx7fq49();
24052
24052
  import_react_devtools_core = __toESM(require_backend(), 1);
24053
24053
  g = globalThis;
24054
24054
  if (typeof g.WebSocket === "undefined") {
@@ -24714,11 +24714,11 @@ var require_shims = __commonJS((exports) => {
24714
24714
  throw new Error("`fetch` is not defined as a global; Either pass `fetch` to the client, `new OpenAI({ fetch })` or polyfill the global, `globalThis.fetch = fetch`");
24715
24715
  }
24716
24716
  function makeReadableStream(...args) {
24717
- const ReadableStream = globalThis.ReadableStream;
24718
- if (typeof ReadableStream === "undefined") {
24717
+ const ReadableStream2 = globalThis.ReadableStream;
24718
+ if (typeof ReadableStream2 === "undefined") {
24719
24719
  throw new Error("`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`");
24720
24720
  }
24721
- return new ReadableStream(...args);
24721
+ return new ReadableStream2(...args);
24722
24722
  }
24723
24723
  function ReadableStreamFrom(iterable) {
24724
24724
  let iter = Symbol.asyncIterator in iterable ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
@@ -31786,7 +31786,8 @@ Rules:
31786
31786
  2. Be specific and actionable \u2014 code examples and exact details over generic advice.
31787
31787
  3. If results don't contain the answer, say so clearly and share what you know from training data.
31788
31788
  4. Prefer recent/authoritative sources. Note when information may be outdated.
31789
- 5. Keep answers concise but thorough \u2014 developers are your audience.`;
31789
+ 5. Keep answers concise but thorough \u2014 developers are your audience.
31790
+ 6. Do NOT use <think> tags or internal reasoning blocks in your response. Output your answer directly.`;
31790
31791
  var RESEARCHER_DOCS_SYSTEM_PROMPT = `You are a documentation research specialist embedded in a coding assistant. You receive documentation search results and synthesize them into a precise, practical answer.
31791
31792
 
31792
31793
  Rules:
@@ -31794,7 +31795,8 @@ Rules:
31794
31795
  2. Include code examples that can be used directly \u2014 prefer showing code over describing it.
31795
31796
  3. Note version-specific behavior when relevant.
31796
31797
  4. Highlight common pitfalls, gotchas, and deprecation warnings.
31797
- 5. If the docs don't cover the question, say so and provide your best guidance from training data.`;
31798
+ 5. If the docs don't cover the question, say so and provide your best guidance from training data.
31799
+ 6. Do NOT use <think> tags or internal reasoning blocks in your response. Output your answer directly.`;
31798
31800
  var GENERAL_AGENT_SYSTEM_PROMPT = `You are a general-purpose coding agent. You receive file contents and conversation context, then produce a thorough, actionable response.
31799
31801
 
31800
31802
  Your strengths:
@@ -31804,8 +31806,8 @@ Your strengths:
31804
31806
 
31805
31807
  Be direct and comprehensive. Provide actual solutions, not descriptions of what to do. If you identify issues or risks, flag them clearly with severity.`;
31806
31808
  var nvidiaClient = new OpenAI({
31807
- apiKey: process.env.NVIDIA_API_KEY || "",
31808
- baseURL: "https://integrate.api.nvidia.com/v1"
31809
+ apiKey: process.env.APEX_API_KEY || "local-proxy",
31810
+ baseURL: process.env.APEX_API_URL || "https://apex-api-ten.vercel.app/v1"
31809
31811
  });
31810
31812
  var session = {
31811
31813
  conversationHistory: [],
@@ -32419,6 +32421,73 @@ var require_tools = __commonJS((exports, module2) => {
32419
32421
  module2.exports = { toolDefs };
32420
32422
  });
32421
32423
 
32424
+ // src/thinking.js
32425
+ var require_thinking = __commonJS((exports, module2) => {
32426
+ function parseThinkBlocks(text) {
32427
+ const thinkRegex = /<think>([\s\S]*?)(?:<\/think>|think>)/g;
32428
+ const thoughts = [];
32429
+ let match;
32430
+ while ((match = thinkRegex.exec(text)) !== null) {
32431
+ const content = match[1].trim();
32432
+ if (content)
32433
+ thoughts.push(content);
32434
+ }
32435
+ const cleaned = text.replace(/<think>[\s\S]*?(?:<\/think>|think>)/g, "").trim();
32436
+ return { thoughts, content: cleaned };
32437
+ }
32438
+ function findThinkClose(text) {
32439
+ const fullClose = text.indexOf("</think>");
32440
+ if (fullClose !== -1)
32441
+ return { pos: fullClose, len: 8 };
32442
+ let searchFrom = 0;
32443
+ while (searchFrom < text.length) {
32444
+ const idx = text.indexOf("think>", searchFrom);
32445
+ if (idx === -1)
32446
+ break;
32447
+ if (idx === 0 || text[idx - 1] !== "<")
32448
+ return { pos: idx, len: 6 };
32449
+ searchFrom = idx + 6;
32450
+ }
32451
+ return null;
32452
+ }
32453
+ function stripStrayCloseTag(text) {
32454
+ return text.replace(/<\/think>/g, "").replace(/(?<!<)think>/g, "");
32455
+ }
32456
+ function splitAtPartialTag(text) {
32457
+ const prefixes = [
32458
+ "</think>",
32459
+ "</think",
32460
+ "</thin",
32461
+ "</thi",
32462
+ "</th",
32463
+ "</t",
32464
+ "</",
32465
+ "<think>",
32466
+ "<think",
32467
+ "<thin",
32468
+ "<thi",
32469
+ "<th",
32470
+ "<t",
32471
+ "<"
32472
+ ];
32473
+ for (const prefix of prefixes) {
32474
+ if (text.endsWith(prefix)) {
32475
+ if (prefix === "</think>" || prefix === "think>") {
32476
+ return { safe: text.slice(0, -prefix.length), pending: "" };
32477
+ }
32478
+ return { safe: text.slice(0, -prefix.length), pending: prefix };
32479
+ }
32480
+ }
32481
+ return { safe: text, pending: "" };
32482
+ }
32483
+ module2.exports = {
32484
+ parseThinkBlocks,
32485
+ findThinkClose,
32486
+ stripStrayCloseTag,
32487
+ splitAtPartialTag
32488
+ };
32489
+ });
32490
+
32422
32491
  // src/toolExecutors.js
32423
32492
  var require_toolExecutors = __commonJS((exports, module2) => {
32424
32493
  var fs2 = __require("fs");
@@ -32451,6 +32520,7 @@ var require_toolExecutors = __commonJS((exports, module2) => {
32451
32520
  resolvePath,
32452
32521
  sleep
32453
32522
  } = require_config();
32523
+ var { parseThinkBlocks } = require_thinking();
32454
32524
  async function streamCompletion(params, onStream) {
32455
32525
  for (let attempt = 0;attempt <= 2; attempt++) {
32456
32526
  let content = "";
@@ -32458,21 +32528,39 @@ var require_toolExecutors = __commonJS((exports, module2) => {
32458
32528
  try {
32459
32529
  if (onStream) {
32460
32530
  const stream = await nvidiaClient.chat.completions.create({ ...params, stream: true });
32531
+ let displayContent = "";
32461
32532
  for await (const chunk of stream) {
32462
32533
  const delta = chunk.choices?.[0]?.delta;
32463
32534
  if (delta?.content) {
32464
32535
  content += delta.content;
32465
- onStream(content || reasoning);
32536
+ const lastOpen = content.lastIndexOf("<think>");
32537
+ const lastClose = content.lastIndexOf("</think>");
32538
+ if (lastOpen <= lastClose || lastOpen === -1) {
32539
+ displayContent = parseThinkBlocks(content).content;
32540
+ }
32541
+ onStream(displayContent || reasoning);
32466
32542
  }
32467
32543
  if (delta?.reasoning_content) {
32468
32544
  reasoning += delta.reasoning_content;
32469
- onStream(content || reasoning);
32545
+ onStream(displayContent || reasoning);
32470
32546
  }
32471
32547
  }
32472
- return content || reasoning || "";
32548
+ let { content: cleaned } = parseThinkBlocks(content);
32549
+ const unclosedIdx = cleaned.lastIndexOf("<think>");
32550
+ if (unclosedIdx !== -1 && cleaned.indexOf("</think>", unclosedIdx) === -1) {
32551
+ cleaned = cleaned.slice(0, unclosedIdx).trim();
32552
+ }
32553
+ return cleaned || reasoning || "";
32473
32554
  } else {
32474
32555
  const response = await nvidiaClient.chat.completions.create(params);
32475
- return response.choices[0]?.message?.content || response.choices[0]?.message?.reasoning_content || "";
32556
+ const rawContent = response.choices[0]?.message?.content || "";
32557
+ const rawReasoning = response.choices[0]?.message?.reasoning_content || "";
32558
+ let { content: cleaned } = parseThinkBlocks(rawContent);
32559
+ const unclosedIdx = cleaned.lastIndexOf("<think>");
32560
+ if (unclosedIdx !== -1 && cleaned.indexOf("</think>", unclosedIdx) === -1) {
32561
+ cleaned = cleaned.slice(0, unclosedIdx).trim();
32562
+ }
32563
+ return cleaned || rawReasoning || "";
32476
32564
  }
32477
32565
  } catch (err) {
32478
32566
  if (err.status === 404 && params.model !== NVIDIA_MODEL && attempt < 2) {
@@ -33671,73 +33759,6 @@ var require_utils3 = __commonJS((exports, module2) => {
33671
33759
  module2.exports = { toolDetailStr };
33672
33760
  });
33673
33761
 
33674
- // src/thinking.js
33675
- var require_thinking = __commonJS((exports, module2) => {
33676
- function parseThinkBlocks(text) {
33677
- const thinkRegex = /<think>([\s\S]*?)(?:<\/think>|think>)/g;
33678
- const thoughts = [];
33679
- let match;
33680
- while ((match = thinkRegex.exec(text)) !== null) {
33681
- const content = match[1].trim();
33682
- if (content)
33683
- thoughts.push(content);
33684
- }
33685
- const cleaned = text.replace(/<think>[\s\S]*?(?:<\/think>|think>)/g, "").trim();
33686
- return { thoughts, content: cleaned };
33687
- }
33688
- function findThinkClose(text) {
33689
- const fullClose = text.indexOf("</think>");
33690
- if (fullClose !== -1)
33691
- return { pos: fullClose, len: 8 };
33692
- let searchFrom = 0;
33693
- while (searchFrom < text.length) {
33694
- const idx = text.indexOf("think>", searchFrom);
33695
- if (idx === -1)
33696
- break;
33697
- if (idx === 0 || text[idx - 1] !== "<")
33698
- return { pos: idx, len: 6 };
33699
- searchFrom = idx + 6;
33700
- }
33701
- return null;
33702
- }
33703
- function stripStrayCloseTag(text) {
33704
- return text.replace(/<\/think>/g, "").replace(/(?<!<)think>/g, "");
33705
- }
33706
- function splitAtPartialTag(text) {
33707
- const prefixes = [
33708
- "</think>",
33709
- "</think",
33710
- "</thin",
33711
- "</thi",
33712
- "</th",
33713
- "</t",
33714
- "</",
33715
- "<think>",
33716
- "<think",
33717
- "<thin",
33718
- "<thi",
33719
- "<th",
33720
- "<t",
33721
- "<"
33722
- ];
33723
- for (const prefix of prefixes) {
33724
- if (text.endsWith(prefix)) {
33725
- if (prefix === "</think>" || prefix === "think>") {
33726
- return { safe: text.slice(0, -prefix.length), pending: "" };
33727
- }
33728
- return { safe: text.slice(0, -prefix.length), pending: prefix };
33729
- }
33730
- }
33731
- return { safe: text, pending: "" };
33732
- }
33733
- module2.exports = {
33734
- parseThinkBlocks,
33735
- findThinkClose,
33736
- stripStrayCloseTag,
33737
- splitAtPartialTag
33738
- };
33739
- });
33740
-
33741
33762
  // src/agent.js
33742
33763
  var require_agent = __commonJS((exports, module2) => {
33743
33764
  var {
@@ -34267,7 +34288,101 @@ var require_jsx_runtime = __commonJS((exports, module2) => {
34267
34288
  } else {}
34268
34289
  });
34269
34290
 
34270
- // node_modules/@opentui/core/index-a215gqtt.js
34291
+ // src/server.js
34292
+ var require_server = __commonJS((exports, module2) => {
34293
+ var OpenAI = require_openai();
34294
+ var NVIDIA_BASE_URL = "https://integrate.api.nvidia.com/v1";
34295
+ var PORT = process.env.APEX_SERVER_PORT || 3579;
34296
+ var serverInstance = null;
34297
+ async function startServer() {
34298
+ if (serverInstance)
34299
+ return serverInstance;
34300
+ const apiKey = process.env.NVIDIA_API_KEY || "";
34301
+ const upstream = new OpenAI({ apiKey, baseURL: NVIDIA_BASE_URL });
34302
+ serverInstance = Bun.serve({
34303
+ port: PORT,
34304
+ async fetch(req) {
34305
+ const url = new URL(req.url);
34306
+ if (url.pathname === "/health") {
34307
+ return new Response(JSON.stringify({ status: "ok" }), {
34308
+ headers: { "Content-Type": "application/json" }
34309
+ });
34310
+ }
34311
+ if (url.pathname === "/v1/chat/completions" && req.method === "POST") {
34312
+ try {
34313
+ const body = await req.json();
34314
+ const isStream = body.stream === true;
34315
+ if (isStream) {
34316
+ const stream = await upstream.chat.completions.create(body);
34317
+ const encoder2 = new TextEncoder;
34318
+ const readable = new ReadableStream({
34319
+ async start(controller) {
34320
+ try {
34321
+ for await (const chunk of stream) {
34322
+ controller.enqueue(encoder2.encode(`data: ${JSON.stringify(chunk)}
34323
+
34324
+ `));
34325
+ }
34326
+ controller.enqueue(encoder2.encode(`data: [DONE]
34327
+
34328
+ `));
34329
+ controller.close();
34330
+ } catch (err) {
34331
+ controller.enqueue(encoder2.encode(`data: ${JSON.stringify({ error: err.message })}
34332
+
34333
+ `));
34334
+ controller.close();
34335
+ }
34336
+ }
34337
+ });
34338
+ return new Response(readable, {
34339
+ headers: {
34340
+ "Content-Type": "text/event-stream",
34341
+ "Cache-Control": "no-cache",
34342
+ Connection: "keep-alive"
34343
+ }
34344
+ });
34345
+ }
34346
+ const result = await upstream.chat.completions.create(body);
34347
+ return new Response(JSON.stringify(result), {
34348
+ headers: { "Content-Type": "application/json" }
34349
+ });
34350
+ } catch (err) {
34351
+ const status = err.status || 500;
34352
+ return new Response(JSON.stringify({ error: { message: err.message, status } }), {
34353
+ status,
34354
+ headers: { "Content-Type": "application/json" }
34355
+ });
34356
+ }
34357
+ }
34358
+ if (url.pathname === "/v1/models" && req.method === "GET") {
34359
+ try {
34360
+ const models = await upstream.models.list();
34361
+ return new Response(JSON.stringify(models), {
34362
+ headers: { "Content-Type": "application/json" }
34363
+ });
34364
+ } catch (err) {
34365
+ return new Response(JSON.stringify({ error: err.message }), {
34366
+ status: 500,
34367
+ headers: { "Content-Type": "application/json" }
34368
+ });
34369
+ }
34370
+ }
34371
+ return new Response("Not Found", { status: 404 });
34372
+ }
34373
+ });
34374
+ return serverInstance;
34375
+ }
34376
+ function getServerURL() {
34377
+ return `http://localhost:${PORT}/v1`;
34378
+ }
34379
+ function getPort() {
34380
+ return PORT;
34381
+ }
34382
+ module2.exports = { startServer, getServerURL, getPort };
34383
+ });
34384
+
34385
+ // node_modules/@opentui/core/index-qr7b6cvh.js
34271
34386
  import { Buffer as Buffer2 } from "buffer";
34272
34387
  import { EventEmitter } from "events";
34273
34388
  import { EventEmitter as EventEmitter2 } from "events";
@@ -34308,7 +34423,7 @@ var highlights_default5 = "./highlights-hk7bwhj4.scm";
34308
34423
  // node_modules/@opentui/core/assets/zig/tree-sitter-zig.wasm
34309
34424
  var tree_sitter_zig_default = "./tree-sitter-zig-e78zbjpm.wasm";
34310
34425
 
34311
- // node_modules/@opentui/core/index-a215gqtt.js
34426
+ // node_modules/@opentui/core/index-qr7b6cvh.js
34312
34427
  import { resolve as resolve2, isAbsolute, parse } from "path";
34313
34428
  import { existsSync } from "fs";
34314
34429
  import { basename, join } from "path";
@@ -34332,13 +34447,17 @@ import { Writable } from "stream";
34332
34447
  import { EventEmitter as EventEmitter7 } from "events";
34333
34448
  import { EventEmitter as EventEmitter9 } from "events";
34334
34449
  var __defProp2 = Object.defineProperty;
34450
+ var __returnValue = (v) => v;
34451
+ function __exportSetter(name, newValue) {
34452
+ this[name] = __returnValue.bind(null, newValue);
34453
+ }
34335
34454
  var __export2 = (target, all) => {
34336
34455
  for (var name in all)
34337
34456
  __defProp2(target, name, {
34338
34457
  get: all[name],
34339
34458
  enumerable: true,
34340
34459
  configurable: true,
34341
- set: (newValue) => all[name] = () => newValue
34460
+ set: __exportSetter.bind(all, name)
34342
34461
  });
34343
34462
  };
34344
34463
  var exports_src = {};
@@ -53747,604 +53866,6 @@ class LineNumberRenderable extends Renderable {
53747
53866
  }
53748
53867
  }
53749
53868
  }
53750
-
53751
- class Diff {
53752
- diff(oldStr, newStr, options = {}) {
53753
- let callback;
53754
- if (typeof options === "function") {
53755
- callback = options;
53756
- options = {};
53757
- } else if ("callback" in options) {
53758
- callback = options.callback;
53759
- }
53760
- const oldString = this.castInput(oldStr, options);
53761
- const newString = this.castInput(newStr, options);
53762
- const oldTokens = this.removeEmpty(this.tokenize(oldString, options));
53763
- const newTokens = this.removeEmpty(this.tokenize(newString, options));
53764
- return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);
53765
- }
53766
- diffWithOptionsObj(oldTokens, newTokens, options, callback) {
53767
- var _a;
53768
- const done = (value) => {
53769
- value = this.postProcess(value, options);
53770
- if (callback) {
53771
- setTimeout(function() {
53772
- callback(value);
53773
- }, 0);
53774
- return;
53775
- } else {
53776
- return value;
53777
- }
53778
- };
53779
- const newLen = newTokens.length, oldLen = oldTokens.length;
53780
- let editLength = 1;
53781
- let maxEditLength = newLen + oldLen;
53782
- if (options.maxEditLength != null) {
53783
- maxEditLength = Math.min(maxEditLength, options.maxEditLength);
53784
- }
53785
- const maxExecutionTime = (_a = options.timeout) !== null && _a !== undefined ? _a : Infinity;
53786
- const abortAfterTimestamp = Date.now() + maxExecutionTime;
53787
- const bestPath = [{ oldPos: -1, lastComponent: undefined }];
53788
- let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);
53789
- if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
53790
- return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));
53791
- }
53792
- let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;
53793
- const execEditLength = () => {
53794
- for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength);diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {
53795
- let basePath;
53796
- const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];
53797
- if (removePath) {
53798
- bestPath[diagonalPath - 1] = undefined;
53799
- }
53800
- let canAdd = false;
53801
- if (addPath) {
53802
- const addPathNewPos = addPath.oldPos - diagonalPath;
53803
- canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;
53804
- }
53805
- const canRemove = removePath && removePath.oldPos + 1 < oldLen;
53806
- if (!canAdd && !canRemove) {
53807
- bestPath[diagonalPath] = undefined;
53808
- continue;
53809
- }
53810
- if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {
53811
- basePath = this.addToPath(addPath, true, false, 0, options);
53812
- } else {
53813
- basePath = this.addToPath(removePath, false, true, 1, options);
53814
- }
53815
- newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);
53816
- if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
53817
- return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;
53818
- } else {
53819
- bestPath[diagonalPath] = basePath;
53820
- if (basePath.oldPos + 1 >= oldLen) {
53821
- maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);
53822
- }
53823
- if (newPos + 1 >= newLen) {
53824
- minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);
53825
- }
53826
- }
53827
- }
53828
- editLength++;
53829
- };
53830
- if (callback) {
53831
- (function exec() {
53832
- setTimeout(function() {
53833
- if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
53834
- return callback(undefined);
53835
- }
53836
- if (!execEditLength()) {
53837
- exec();
53838
- }
53839
- }, 0);
53840
- })();
53841
- } else {
53842
- while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
53843
- const ret = execEditLength();
53844
- if (ret) {
53845
- return ret;
53846
- }
53847
- }
53848
- }
53849
- }
53850
- addToPath(path2, added, removed, oldPosInc, options) {
53851
- const last = path2.lastComponent;
53852
- if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
53853
- return {
53854
- oldPos: path2.oldPos + oldPosInc,
53855
- lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
53856
- };
53857
- } else {
53858
- return {
53859
- oldPos: path2.oldPos + oldPosInc,
53860
- lastComponent: { count: 1, added, removed, previousComponent: last }
53861
- };
53862
- }
53863
- }
53864
- extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {
53865
- const newLen = newTokens.length, oldLen = oldTokens.length;
53866
- let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;
53867
- while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {
53868
- newPos++;
53869
- oldPos++;
53870
- commonCount++;
53871
- if (options.oneChangePerToken) {
53872
- basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
53873
- }
53874
- }
53875
- if (commonCount && !options.oneChangePerToken) {
53876
- basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };
53877
- }
53878
- basePath.oldPos = oldPos;
53879
- return newPos;
53880
- }
53881
- equals(left, right, options) {
53882
- if (options.comparator) {
53883
- return options.comparator(left, right);
53884
- } else {
53885
- return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
53886
- }
53887
- }
53888
- removeEmpty(array) {
53889
- const ret = [];
53890
- for (let i = 0;i < array.length; i++) {
53891
- if (array[i]) {
53892
- ret.push(array[i]);
53893
- }
53894
- }
53895
- return ret;
53896
- }
53897
- castInput(value, options) {
53898
- return value;
53899
- }
53900
- tokenize(value, options) {
53901
- return Array.from(value);
53902
- }
53903
- join(chars) {
53904
- return chars.join("");
53905
- }
53906
- postProcess(changeObjects, options) {
53907
- return changeObjects;
53908
- }
53909
- get useLongestToken() {
53910
- return false;
53911
- }
53912
- buildValues(lastComponent, newTokens, oldTokens) {
53913
- const components = [];
53914
- let nextComponent;
53915
- while (lastComponent) {
53916
- components.push(lastComponent);
53917
- nextComponent = lastComponent.previousComponent;
53918
- delete lastComponent.previousComponent;
53919
- lastComponent = nextComponent;
53920
- }
53921
- components.reverse();
53922
- const componentLen = components.length;
53923
- let componentPos = 0, newPos = 0, oldPos = 0;
53924
- for (;componentPos < componentLen; componentPos++) {
53925
- const component = components[componentPos];
53926
- if (!component.removed) {
53927
- if (!component.added && this.useLongestToken) {
53928
- let value = newTokens.slice(newPos, newPos + component.count);
53929
- value = value.map(function(value2, i) {
53930
- const oldValue = oldTokens[oldPos + i];
53931
- return oldValue.length > value2.length ? oldValue : value2;
53932
- });
53933
- component.value = this.join(value);
53934
- } else {
53935
- component.value = this.join(newTokens.slice(newPos, newPos + component.count));
53936
- }
53937
- newPos += component.count;
53938
- if (!component.added) {
53939
- oldPos += component.count;
53940
- }
53941
- } else {
53942
- component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
53943
- oldPos += component.count;
53944
- }
53945
- }
53946
- return components;
53947
- }
53948
- }
53949
-
53950
- class CharacterDiff extends Diff {
53951
- }
53952
- var characterDiff = new CharacterDiff;
53953
- function longestCommonPrefix(str1, str2) {
53954
- let i;
53955
- for (i = 0;i < str1.length && i < str2.length; i++) {
53956
- if (str1[i] != str2[i]) {
53957
- return str1.slice(0, i);
53958
- }
53959
- }
53960
- return str1.slice(0, i);
53961
- }
53962
- function longestCommonSuffix(str1, str2) {
53963
- let i;
53964
- if (!str1 || !str2 || str1[str1.length - 1] != str2[str2.length - 1]) {
53965
- return "";
53966
- }
53967
- for (i = 0;i < str1.length && i < str2.length; i++) {
53968
- if (str1[str1.length - (i + 1)] != str2[str2.length - (i + 1)]) {
53969
- return str1.slice(-i);
53970
- }
53971
- }
53972
- return str1.slice(-i);
53973
- }
53974
- function replacePrefix(string, oldPrefix, newPrefix) {
53975
- if (string.slice(0, oldPrefix.length) != oldPrefix) {
53976
- throw Error(`string ${JSON.stringify(string)} doesn't start with prefix ${JSON.stringify(oldPrefix)}; this is a bug`);
53977
- }
53978
- return newPrefix + string.slice(oldPrefix.length);
53979
- }
53980
- function replaceSuffix(string, oldSuffix, newSuffix) {
53981
- if (!oldSuffix) {
53982
- return string + newSuffix;
53983
- }
53984
- if (string.slice(-oldSuffix.length) != oldSuffix) {
53985
- throw Error(`string ${JSON.stringify(string)} doesn't end with suffix ${JSON.stringify(oldSuffix)}; this is a bug`);
53986
- }
53987
- return string.slice(0, -oldSuffix.length) + newSuffix;
53988
- }
53989
- function removePrefix(string, oldPrefix) {
53990
- return replacePrefix(string, oldPrefix, "");
53991
- }
53992
- function removeSuffix(string, oldSuffix) {
53993
- return replaceSuffix(string, oldSuffix, "");
53994
- }
53995
- function maximumOverlap(string1, string2) {
53996
- return string2.slice(0, overlapCount(string1, string2));
53997
- }
53998
- function overlapCount(a, b) {
53999
- let startA = 0;
54000
- if (a.length > b.length) {
54001
- startA = a.length - b.length;
54002
- }
54003
- let endB = b.length;
54004
- if (a.length < b.length) {
54005
- endB = a.length;
54006
- }
54007
- const map = Array(endB);
54008
- let k = 0;
54009
- map[0] = 0;
54010
- for (let j = 1;j < endB; j++) {
54011
- if (b[j] == b[k]) {
54012
- map[j] = map[k];
54013
- } else {
54014
- map[j] = k;
54015
- }
54016
- while (k > 0 && b[j] != b[k]) {
54017
- k = map[k];
54018
- }
54019
- if (b[j] == b[k]) {
54020
- k++;
54021
- }
54022
- }
54023
- k = 0;
54024
- for (let i = startA;i < a.length; i++) {
54025
- while (k > 0 && a[i] != b[k]) {
54026
- k = map[k];
54027
- }
54028
- if (a[i] == b[k]) {
54029
- k++;
54030
- }
54031
- }
54032
- return k;
54033
- }
54034
- function trailingWs(string) {
54035
- let i;
54036
- for (i = string.length - 1;i >= 0; i--) {
54037
- if (!string[i].match(/\s/)) {
54038
- break;
54039
- }
54040
- }
54041
- return string.substring(i + 1);
54042
- }
54043
- function leadingWs(string) {
54044
- const match = string.match(/^\s*/);
54045
- return match ? match[0] : "";
54046
- }
54047
- var extendedWordChars = "a-zA-Z0-9_\\u{C0}-\\u{FF}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}";
54048
- var tokenizeIncludingWhitespace = new RegExp(`[${extendedWordChars}]+|\\s+|[^${extendedWordChars}]`, "ug");
54049
-
54050
- class WordDiff extends Diff {
54051
- equals(left, right, options) {
54052
- if (options.ignoreCase) {
54053
- left = left.toLowerCase();
54054
- right = right.toLowerCase();
54055
- }
54056
- return left.trim() === right.trim();
54057
- }
54058
- tokenize(value, options = {}) {
54059
- let parts;
54060
- if (options.intlSegmenter) {
54061
- const segmenter = options.intlSegmenter;
54062
- if (segmenter.resolvedOptions().granularity != "word") {
54063
- throw new Error('The segmenter passed must have a granularity of "word"');
54064
- }
54065
- parts = Array.from(segmenter.segment(value), (segment) => segment.segment);
54066
- } else {
54067
- parts = value.match(tokenizeIncludingWhitespace) || [];
54068
- }
54069
- const tokens = [];
54070
- let prevPart = null;
54071
- parts.forEach((part) => {
54072
- if (/\s/.test(part)) {
54073
- if (prevPart == null) {
54074
- tokens.push(part);
54075
- } else {
54076
- tokens.push(tokens.pop() + part);
54077
- }
54078
- } else if (prevPart != null && /\s/.test(prevPart)) {
54079
- if (tokens[tokens.length - 1] == prevPart) {
54080
- tokens.push(tokens.pop() + part);
54081
- } else {
54082
- tokens.push(prevPart + part);
54083
- }
54084
- } else {
54085
- tokens.push(part);
54086
- }
54087
- prevPart = part;
54088
- });
54089
- return tokens;
54090
- }
54091
- join(tokens) {
54092
- return tokens.map((token, i) => {
54093
- if (i == 0) {
54094
- return token;
54095
- } else {
54096
- return token.replace(/^\s+/, "");
54097
- }
54098
- }).join("");
54099
- }
54100
- postProcess(changes, options) {
54101
- if (!changes || options.oneChangePerToken) {
54102
- return changes;
54103
- }
54104
- let lastKeep = null;
54105
- let insertion = null;
54106
- let deletion = null;
54107
- changes.forEach((change) => {
54108
- if (change.added) {
54109
- insertion = change;
54110
- } else if (change.removed) {
54111
- deletion = change;
54112
- } else {
54113
- if (insertion || deletion) {
54114
- dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, change);
54115
- }
54116
- lastKeep = change;
54117
- insertion = null;
54118
- deletion = null;
54119
- }
54120
- });
54121
- if (insertion || deletion) {
54122
- dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, null);
54123
- }
54124
- return changes;
54125
- }
54126
- }
54127
- var wordDiff = new WordDiff;
54128
- function dedupeWhitespaceInChangeObjects(startKeep, deletion, insertion, endKeep) {
54129
- if (deletion && insertion) {
54130
- const oldWsPrefix = leadingWs(deletion.value);
54131
- const oldWsSuffix = trailingWs(deletion.value);
54132
- const newWsPrefix = leadingWs(insertion.value);
54133
- const newWsSuffix = trailingWs(insertion.value);
54134
- if (startKeep) {
54135
- const commonWsPrefix = longestCommonPrefix(oldWsPrefix, newWsPrefix);
54136
- startKeep.value = replaceSuffix(startKeep.value, newWsPrefix, commonWsPrefix);
54137
- deletion.value = removePrefix(deletion.value, commonWsPrefix);
54138
- insertion.value = removePrefix(insertion.value, commonWsPrefix);
54139
- }
54140
- if (endKeep) {
54141
- const commonWsSuffix = longestCommonSuffix(oldWsSuffix, newWsSuffix);
54142
- endKeep.value = replacePrefix(endKeep.value, newWsSuffix, commonWsSuffix);
54143
- deletion.value = removeSuffix(deletion.value, commonWsSuffix);
54144
- insertion.value = removeSuffix(insertion.value, commonWsSuffix);
54145
- }
54146
- } else if (insertion) {
54147
- if (startKeep) {
54148
- const ws = leadingWs(insertion.value);
54149
- insertion.value = insertion.value.substring(ws.length);
54150
- }
54151
- if (endKeep) {
54152
- const ws = leadingWs(endKeep.value);
54153
- endKeep.value = endKeep.value.substring(ws.length);
54154
- }
54155
- } else if (startKeep && endKeep) {
54156
- const newWsFull = leadingWs(endKeep.value), delWsStart = leadingWs(deletion.value), delWsEnd = trailingWs(deletion.value);
54157
- const newWsStart = longestCommonPrefix(newWsFull, delWsStart);
54158
- deletion.value = removePrefix(deletion.value, newWsStart);
54159
- const newWsEnd = longestCommonSuffix(removePrefix(newWsFull, newWsStart), delWsEnd);
54160
- deletion.value = removeSuffix(deletion.value, newWsEnd);
54161
- endKeep.value = replacePrefix(endKeep.value, newWsFull, newWsEnd);
54162
- startKeep.value = replaceSuffix(startKeep.value, newWsFull, newWsFull.slice(0, newWsFull.length - newWsEnd.length));
54163
- } else if (endKeep) {
54164
- const endKeepWsPrefix = leadingWs(endKeep.value);
54165
- const deletionWsSuffix = trailingWs(deletion.value);
54166
- const overlap = maximumOverlap(deletionWsSuffix, endKeepWsPrefix);
54167
- deletion.value = removeSuffix(deletion.value, overlap);
54168
- } else if (startKeep) {
54169
- const startKeepWsSuffix = trailingWs(startKeep.value);
54170
- const deletionWsPrefix = leadingWs(deletion.value);
54171
- const overlap = maximumOverlap(startKeepWsSuffix, deletionWsPrefix);
54172
- deletion.value = removePrefix(deletion.value, overlap);
54173
- }
54174
- }
54175
-
54176
- class WordsWithSpaceDiff extends Diff {
54177
- tokenize(value) {
54178
- const regex = new RegExp(`(\\r?\\n)|[${extendedWordChars}]+|[^\\S\\n\\r]+|[^${extendedWordChars}]`, "ug");
54179
- return value.match(regex) || [];
54180
- }
54181
- }
54182
- var wordsWithSpaceDiff = new WordsWithSpaceDiff;
54183
-
54184
- class LineDiff extends Diff {
54185
- constructor() {
54186
- super(...arguments);
54187
- this.tokenize = tokenize;
54188
- }
54189
- equals(left, right, options) {
54190
- if (options.ignoreWhitespace) {
54191
- if (!options.newlineIsToken || !left.includes(`
54192
- `)) {
54193
- left = left.trim();
54194
- }
54195
- if (!options.newlineIsToken || !right.includes(`
54196
- `)) {
54197
- right = right.trim();
54198
- }
54199
- } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
54200
- if (left.endsWith(`
54201
- `)) {
54202
- left = left.slice(0, -1);
54203
- }
54204
- if (right.endsWith(`
54205
- `)) {
54206
- right = right.slice(0, -1);
54207
- }
54208
- }
54209
- return super.equals(left, right, options);
54210
- }
54211
- }
54212
- var lineDiff = new LineDiff;
54213
- function tokenize(value, options) {
54214
- if (options.stripTrailingCr) {
54215
- value = value.replace(/\r\n/g, `
54216
- `);
54217
- }
54218
- const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/);
54219
- if (!linesAndNewlines[linesAndNewlines.length - 1]) {
54220
- linesAndNewlines.pop();
54221
- }
54222
- for (let i = 0;i < linesAndNewlines.length; i++) {
54223
- const line = linesAndNewlines[i];
54224
- if (i % 2 && !options.newlineIsToken) {
54225
- retLines[retLines.length - 1] += line;
54226
- } else {
54227
- retLines.push(line);
54228
- }
54229
- }
54230
- return retLines;
54231
- }
54232
- function isSentenceEndPunct(char) {
54233
- return char == "." || char == "!" || char == "?";
54234
- }
54235
-
54236
- class SentenceDiff extends Diff {
54237
- tokenize(value) {
54238
- var _a;
54239
- const result = [];
54240
- let tokenStartI = 0;
54241
- for (let i = 0;i < value.length; i++) {
54242
- if (i == value.length - 1) {
54243
- result.push(value.slice(tokenStartI));
54244
- break;
54245
- }
54246
- if (isSentenceEndPunct(value[i]) && value[i + 1].match(/\s/)) {
54247
- result.push(value.slice(tokenStartI, i + 1));
54248
- i = tokenStartI = i + 1;
54249
- while ((_a = value[i + 1]) === null || _a === undefined ? undefined : _a.match(/\s/)) {
54250
- i++;
54251
- }
54252
- result.push(value.slice(tokenStartI, i + 1));
54253
- tokenStartI = i + 1;
54254
- }
54255
- }
54256
- return result;
54257
- }
54258
- }
54259
- var sentenceDiff = new SentenceDiff;
54260
-
54261
- class CssDiff extends Diff {
54262
- tokenize(value) {
54263
- return value.split(/([{}:;,]|\s+)/);
54264
- }
54265
- }
54266
- var cssDiff = new CssDiff;
54267
-
54268
- class JsonDiff extends Diff {
54269
- constructor() {
54270
- super(...arguments);
54271
- this.tokenize = tokenize;
54272
- }
54273
- get useLongestToken() {
54274
- return true;
54275
- }
54276
- castInput(value, options) {
54277
- const { undefinedReplacement, stringifyReplacer = (k, v) => typeof v === "undefined" ? undefinedReplacement : v } = options;
54278
- return typeof value === "string" ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), null, " ");
54279
- }
54280
- equals(left, right, options) {
54281
- return super.equals(left.replace(/,([\r\n])/g, "$1"), right.replace(/,([\r\n])/g, "$1"), options);
54282
- }
54283
- }
54284
- var jsonDiff = new JsonDiff;
54285
- function canonicalize(obj, stack, replacementStack, replacer, key) {
54286
- stack = stack || [];
54287
- replacementStack = replacementStack || [];
54288
- if (replacer) {
54289
- obj = replacer(key === undefined ? "" : key, obj);
54290
- }
54291
- let i;
54292
- for (i = 0;i < stack.length; i += 1) {
54293
- if (stack[i] === obj) {
54294
- return replacementStack[i];
54295
- }
54296
- }
54297
- let canonicalizedObj;
54298
- if (Object.prototype.toString.call(obj) === "[object Array]") {
54299
- stack.push(obj);
54300
- canonicalizedObj = new Array(obj.length);
54301
- replacementStack.push(canonicalizedObj);
54302
- for (i = 0;i < obj.length; i += 1) {
54303
- canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, String(i));
54304
- }
54305
- stack.pop();
54306
- replacementStack.pop();
54307
- return canonicalizedObj;
54308
- }
54309
- if (obj && obj.toJSON) {
54310
- obj = obj.toJSON();
54311
- }
54312
- if (typeof obj === "object" && obj !== null) {
54313
- stack.push(obj);
54314
- canonicalizedObj = {};
54315
- replacementStack.push(canonicalizedObj);
54316
- const sortedKeys = [];
54317
- let key2;
54318
- for (key2 in obj) {
54319
- if (Object.prototype.hasOwnProperty.call(obj, key2)) {
54320
- sortedKeys.push(key2);
54321
- }
54322
- }
54323
- sortedKeys.sort();
54324
- for (i = 0;i < sortedKeys.length; i += 1) {
54325
- key2 = sortedKeys[i];
54326
- canonicalizedObj[key2] = canonicalize(obj[key2], stack, replacementStack, replacer, key2);
54327
- }
54328
- stack.pop();
54329
- replacementStack.pop();
54330
- } else {
54331
- canonicalizedObj = obj;
54332
- }
54333
- return canonicalizedObj;
54334
- }
54335
-
54336
- class ArrayDiff extends Diff {
54337
- tokenize(value) {
54338
- return value.slice();
54339
- }
54340
- join(value) {
54341
- return value;
54342
- }
54343
- removeEmpty(value) {
54344
- return value;
54345
- }
54346
- }
54347
- var arrayDiff = new ArrayDiff;
54348
53869
  function parsePatch(uniDiff) {
54349
53870
  const diffstr = uniDiff.split(/\n/), list = [];
54350
53871
  let i = 0;
@@ -56757,6 +56278,7 @@ class TextTableRenderable extends Renderable {
56757
56278
  _content;
56758
56279
  _wrapMode;
56759
56280
  _columnWidthMode;
56281
+ _columnFitter;
56760
56282
  _cellPadding;
56761
56283
  _showBorders;
56762
56284
  _border;
@@ -56784,8 +56306,9 @@ class TextTableRenderable extends Renderable {
56784
56306
  _cachedMeasureWidth = undefined;
56785
56307
  _defaultOptions = {
56786
56308
  content: [],
56787
- wrapMode: "none",
56788
- columnWidthMode: "content",
56309
+ wrapMode: "word",
56310
+ columnWidthMode: "full",
56311
+ columnFitter: "proportional",
56789
56312
  cellPadding: 0,
56790
56313
  showBorders: true,
56791
56314
  border: true,
@@ -56802,10 +56325,11 @@ class TextTableRenderable extends Renderable {
56802
56325
  attributes: 0
56803
56326
  };
56804
56327
  constructor(ctx, options = {}) {
56805
- super(ctx, { ...options, buffered: true });
56328
+ super(ctx, { ...options, flexShrink: options.flexShrink ?? 0, buffered: true });
56806
56329
  this._content = options.content ?? this._defaultOptions.content;
56807
56330
  this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode;
56808
56331
  this._columnWidthMode = options.columnWidthMode ?? this._defaultOptions.columnWidthMode;
56332
+ this._columnFitter = this.resolveColumnFitter(options.columnFitter);
56809
56333
  this._cellPadding = this.resolveCellPadding(options.cellPadding);
56810
56334
  this._showBorders = options.showBorders ?? this._defaultOptions.showBorders;
56811
56335
  this._border = options.border ?? this._defaultOptions.border;
@@ -56854,6 +56378,16 @@ class TextTableRenderable extends Renderable {
56854
56378
  this._columnWidthMode = value;
56855
56379
  this.invalidateLayoutAndRaster();
56856
56380
  }
56381
+ get columnFitter() {
56382
+ return this._columnFitter;
56383
+ }
56384
+ set columnFitter(value) {
56385
+ const next = this.resolveColumnFitter(value);
56386
+ if (this._columnFitter === next)
56387
+ return;
56388
+ this._columnFitter = next;
56389
+ this.invalidateLayoutAndRaster();
56390
+ }
56857
56391
  get cellPadding() {
56858
56392
  return this._cellPadding;
56859
56393
  }
@@ -57007,7 +56541,7 @@ class TextTableRenderable extends Renderable {
57007
56541
  super.destroySelf();
57008
56542
  }
57009
56543
  setupMeasureFunc() {
57010
- const measureFunc = (width, widthMode, height, heightMode) => {
56544
+ const measureFunc = (width, widthMode, _height, _heightMode) => {
57011
56545
  const hasWidthConstraint = widthMode !== MeasureMode.Undefined && Number.isFinite(width);
57012
56546
  const rawWidthConstraint = hasWidthConstraint ? Math.max(1, Math.floor(width)) : undefined;
57013
56547
  const widthConstraint = this.resolveLayoutWidthConstraint(rawWidthConstraint);
@@ -57019,9 +56553,6 @@ class TextTableRenderable extends Renderable {
57019
56553
  if (widthMode === MeasureMode.AtMost && rawWidthConstraint !== undefined && this._positionType !== "absolute") {
57020
56554
  measuredWidth = Math.min(rawWidthConstraint, measuredWidth);
57021
56555
  }
57022
- if (heightMode === MeasureMode.AtMost && Number.isFinite(height) && this._positionType !== "absolute") {
57023
- measuredHeight = Math.min(Math.max(1, Math.floor(height)), measuredHeight);
57024
- }
57025
56556
  return {
57026
56557
  width: measuredWidth,
57027
56558
  height: measuredHeight
@@ -57193,6 +56724,9 @@ class TextTableRenderable extends Renderable {
57193
56724
  tableHeight: (rowOffsets[rowOffsets.length - 1] ?? 0) + 1
57194
56725
  };
57195
56726
  }
56727
+ isFullWidthMode() {
56728
+ return this._columnWidthMode === "full";
56729
+ }
57196
56730
  computeColumnWidths(maxTableWidth, borderLayout) {
57197
56731
  const horizontalPadding = this.getHorizontalCellPadding();
57198
56732
  const intrinsicWidths = new Array(this._columnCount).fill(1 + horizontalPadding);
@@ -57215,7 +56749,7 @@ class TextTableRenderable extends Renderable {
57215
56749
  return intrinsicWidths;
57216
56750
  }
57217
56751
  if (currentWidth < maxContentWidth) {
57218
- if (this._columnWidthMode === "fill") {
56752
+ if (this.isFullWidthMode()) {
57219
56753
  return this.expandColumnWidths(intrinsicWidths, maxContentWidth);
57220
56754
  }
57221
56755
  return intrinsicWidths;
@@ -57245,6 +56779,12 @@ class TextTableRenderable extends Renderable {
57245
56779
  return expanded;
57246
56780
  }
57247
56781
  fitColumnWidths(widths, targetContentWidth) {
56782
+ if (this._columnFitter === "balanced") {
56783
+ return this.fitColumnWidthsBalanced(widths, targetContentWidth);
56784
+ }
56785
+ return this.fitColumnWidthsProportional(widths, targetContentWidth);
56786
+ }
56787
+ fitColumnWidthsProportional(widths, targetContentWidth) {
57248
56788
  const minWidth = 1 + this.getHorizontalCellPadding();
57249
56789
  const hardMinWidths = new Array(widths.length).fill(minWidth);
57250
56790
  const baseWidths = widths.map((width) => Math.max(1, Math.floor(width)));
@@ -57295,6 +56835,80 @@ class TextTableRenderable extends Renderable {
57295
56835
  }
57296
56836
  return baseWidths.map((width, idx) => Math.max(floorWidths[idx], width - integerShrink[idx]));
57297
56837
  }
56838
+ fitColumnWidthsBalanced(widths, targetContentWidth) {
56839
+ const minWidth = 1 + this.getHorizontalCellPadding();
56840
+ const hardMinWidths = new Array(widths.length).fill(minWidth);
56841
+ const baseWidths = widths.map((width) => Math.max(1, Math.floor(width)));
56842
+ const totalBaseWidth = baseWidths.reduce((sum, width) => sum + width, 0);
56843
+ const columns = baseWidths.length;
56844
+ if (columns === 0 || totalBaseWidth <= targetContentWidth) {
56845
+ return baseWidths;
56846
+ }
56847
+ const evenShare = Math.max(minWidth, Math.floor(targetContentWidth / columns));
56848
+ const preferredMinWidths = baseWidths.map((width) => Math.min(width, evenShare));
56849
+ const preferredMinTotal = preferredMinWidths.reduce((sum, width) => sum + width, 0);
56850
+ const floorWidths = preferredMinTotal <= targetContentWidth ? preferredMinWidths : hardMinWidths;
56851
+ const floorTotal = floorWidths.reduce((sum, width) => sum + width, 0);
56852
+ const clampedTarget = Math.max(floorTotal, targetContentWidth);
56853
+ if (totalBaseWidth <= clampedTarget) {
56854
+ return baseWidths;
56855
+ }
56856
+ const shrinkable = baseWidths.map((width, idx) => width - floorWidths[idx]);
56857
+ const totalShrinkable = shrinkable.reduce((sum, value) => sum + value, 0);
56858
+ if (totalShrinkable <= 0) {
56859
+ return [...floorWidths];
56860
+ }
56861
+ const targetShrink = totalBaseWidth - clampedTarget;
56862
+ const shrink = this.allocateShrinkByWeight(shrinkable, targetShrink, "sqrt");
56863
+ return baseWidths.map((width, idx) => Math.max(floorWidths[idx], width - shrink[idx]));
56864
+ }
56865
+ allocateShrinkByWeight(shrinkable, targetShrink, mode) {
56866
+ const shrink = new Array(shrinkable.length).fill(0);
56867
+ if (targetShrink <= 0) {
56868
+ return shrink;
56869
+ }
56870
+ const weights = shrinkable.map((value) => {
56871
+ if (value <= 0) {
56872
+ return 0;
56873
+ }
56874
+ return mode === "sqrt" ? Math.sqrt(value) : value;
56875
+ });
56876
+ const totalWeight = weights.reduce((sum, value) => sum + value, 0);
56877
+ if (totalWeight <= 0) {
56878
+ return shrink;
56879
+ }
56880
+ const fractions = new Array(shrinkable.length).fill(0);
56881
+ let usedShrink = 0;
56882
+ for (let idx = 0;idx < shrinkable.length; idx++) {
56883
+ if (shrinkable[idx] <= 0 || weights[idx] <= 0)
56884
+ continue;
56885
+ const exact = weights[idx] / totalWeight * targetShrink;
56886
+ const whole = Math.min(shrinkable[idx], Math.floor(exact));
56887
+ shrink[idx] = whole;
56888
+ fractions[idx] = exact - whole;
56889
+ usedShrink += whole;
56890
+ }
56891
+ let remainingShrink = targetShrink - usedShrink;
56892
+ while (remainingShrink > 0) {
56893
+ let bestIdx = -1;
56894
+ let bestFraction = -1;
56895
+ for (let idx = 0;idx < shrinkable.length; idx++) {
56896
+ if (shrinkable[idx] - shrink[idx] <= 0)
56897
+ continue;
56898
+ if (bestIdx === -1 || fractions[idx] > bestFraction || fractions[idx] === bestFraction && shrinkable[idx] > shrinkable[bestIdx]) {
56899
+ bestIdx = idx;
56900
+ bestFraction = fractions[idx];
56901
+ }
56902
+ }
56903
+ if (bestIdx === -1) {
56904
+ break;
56905
+ }
56906
+ shrink[bestIdx] += 1;
56907
+ fractions[bestIdx] = 0;
56908
+ remainingShrink -= 1;
56909
+ }
56910
+ return shrink;
56911
+ }
57298
56912
  computeRowHeights(columnWidths) {
57299
56913
  const horizontalPadding = this.getHorizontalCellPadding();
57300
56914
  const verticalPadding = this.getVerticalCellPadding();
@@ -57618,7 +57232,7 @@ class TextTableRenderable extends Renderable {
57618
57232
  if (width === undefined || !Number.isFinite(width) || width <= 0) {
57619
57233
  return;
57620
57234
  }
57621
- if (this._wrapMode !== "none" || this._columnWidthMode === "fill") {
57235
+ if (this._wrapMode !== "none" || this.isFullWidthMode()) {
57622
57236
  return Math.max(1, Math.floor(width));
57623
57237
  }
57624
57238
  return;
@@ -57629,6 +57243,12 @@ class TextTableRenderable extends Renderable {
57629
57243
  getVerticalCellPadding() {
57630
57244
  return this._cellPadding * 2;
57631
57245
  }
57246
+ resolveColumnFitter(value) {
57247
+ if (value === undefined) {
57248
+ return this._defaultOptions.columnFitter;
57249
+ }
57250
+ return value === "balanced" ? "balanced" : "proportional";
57251
+ }
57632
57252
  resolveCellPadding(value) {
57633
57253
  if (value === undefined || !Number.isFinite(value)) {
57634
57254
  return this._defaultOptions.cellPadding;
@@ -59404,8 +59024,9 @@ class MarkdownRenderable extends Renderable {
59404
59024
  resolveTableRenderableOptions() {
59405
59025
  const borders = this._tableOptions?.borders ?? true;
59406
59026
  return {
59407
- columnWidthMode: this._tableOptions?.widthMode ?? "content",
59408
- wrapMode: this._tableOptions?.wrapMode ?? "none",
59027
+ columnWidthMode: this._tableOptions?.widthMode ?? "full",
59028
+ columnFitter: this._tableOptions?.columnFitter ?? "proportional",
59029
+ wrapMode: this._tableOptions?.wrapMode ?? "word",
59409
59030
  cellPadding: this._tableOptions?.cellPadding ?? 0,
59410
59031
  border: borders,
59411
59032
  outerBorder: this._tableOptions?.outerBorder ?? borders,
@@ -59417,6 +59038,7 @@ class MarkdownRenderable extends Renderable {
59417
59038
  }
59418
59039
  applyTableRenderableOptions(tableRenderable, options) {
59419
59040
  tableRenderable.columnWidthMode = options.columnWidthMode;
59041
+ tableRenderable.columnFitter = options.columnFitter;
59420
59042
  tableRenderable.wrapMode = options.wrapMode;
59421
59043
  tableRenderable.cellPadding = options.cellPadding;
59422
59044
  tableRenderable.border = options.border;
@@ -59447,6 +59069,7 @@ class MarkdownRenderable extends Renderable {
59447
59069
  width: "100%",
59448
59070
  marginBottom,
59449
59071
  columnWidthMode: options.columnWidthMode,
59072
+ columnFitter: options.columnFitter,
59450
59073
  wrapMode: options.wrapMode,
59451
59074
  cellPadding: options.cellPadding,
59452
59075
  border: options.border,
@@ -60306,6 +59929,34 @@ class ContentRenderable extends BoxRenderable {
60306
59929
  return this.getChildrenSortedByPrimaryAxis().map((child) => child.num);
60307
59930
  }
60308
59931
  }
59932
+ var SCROLLBOX_PADDING_KEYS = [
59933
+ "padding",
59934
+ "paddingX",
59935
+ "paddingY",
59936
+ "paddingTop",
59937
+ "paddingRight",
59938
+ "paddingBottom",
59939
+ "paddingLeft"
59940
+ ];
59941
+ function pickScrollBoxPadding(options) {
59942
+ if (!options)
59943
+ return {};
59944
+ const picked = {};
59945
+ for (const key of SCROLLBOX_PADDING_KEYS) {
59946
+ const value = options[key];
59947
+ if (value !== undefined) {
59948
+ picked[key] = value;
59949
+ }
59950
+ }
59951
+ return picked;
59952
+ }
59953
+ function stripScrollBoxPadding(options) {
59954
+ const sanitized = { ...options };
59955
+ for (const key of SCROLLBOX_PADDING_KEYS) {
59956
+ delete sanitized[key];
59957
+ }
59958
+ return sanitized;
59959
+ }
60309
59960
 
60310
59961
  class ScrollBoxRenderable extends BoxRenderable {
60311
59962
  static idCounter = 0;
@@ -60453,27 +60104,38 @@ class ScrollBoxRenderable extends BoxRenderable {
60453
60104
  this._isApplyingStickyScroll = wasApplyingStickyScroll;
60454
60105
  }
60455
60106
  }
60456
- constructor(ctx, {
60457
- wrapperOptions,
60458
- viewportOptions,
60459
- contentOptions,
60460
- rootOptions,
60461
- scrollbarOptions,
60462
- verticalScrollbarOptions,
60463
- horizontalScrollbarOptions,
60464
- stickyScroll = false,
60465
- stickyStart,
60466
- scrollX = false,
60467
- scrollY = true,
60468
- scrollAcceleration,
60469
- viewportCulling = true,
60470
- ...options
60471
- }) {
60107
+ constructor(ctx, options) {
60108
+ const {
60109
+ wrapperOptions,
60110
+ viewportOptions,
60111
+ contentOptions,
60112
+ rootOptions,
60113
+ scrollbarOptions,
60114
+ verticalScrollbarOptions,
60115
+ horizontalScrollbarOptions,
60116
+ stickyScroll = false,
60117
+ stickyStart,
60118
+ scrollX = false,
60119
+ scrollY = true,
60120
+ scrollAcceleration,
60121
+ viewportCulling = true,
60122
+ ...rootBoxOptions
60123
+ } = options;
60124
+ const forwardedContentPadding = {
60125
+ ...pickScrollBoxPadding(rootBoxOptions),
60126
+ ...pickScrollBoxPadding(rootOptions)
60127
+ };
60128
+ const sanitizedRootBoxOptions = stripScrollBoxPadding(rootBoxOptions);
60129
+ const sanitizedRootOptions = rootOptions ? stripScrollBoxPadding(rootOptions) : undefined;
60130
+ const mergedContentOptions = {
60131
+ ...forwardedContentPadding,
60132
+ ...contentOptions
60133
+ };
60472
60134
  super(ctx, {
60473
60135
  flexDirection: "row",
60474
60136
  alignItems: "stretch",
60475
- ...options,
60476
- ...rootOptions
60137
+ ...sanitizedRootBoxOptions,
60138
+ ...sanitizedRootOptions
60477
60139
  });
60478
60140
  this.internalId = ScrollBoxRenderable.idCounter++;
60479
60141
  this._stickyScroll = stickyScroll;
@@ -60505,7 +60167,7 @@ class ScrollBoxRenderable extends BoxRenderable {
60505
60167
  onSizeChange: () => {
60506
60168
  this.recalculateBarProps();
60507
60169
  },
60508
- ...contentOptions,
60170
+ ...mergedContentOptions,
60509
60171
  id: `scroll-box-content-${this.internalId}`
60510
60172
  });
60511
60173
  this.viewport.add(this.content);
@@ -60821,6 +60483,34 @@ class ScrollBoxRenderable extends BoxRenderable {
60821
60483
  this.requestRender();
60822
60484
  });
60823
60485
  }
60486
+ set padding(value) {
60487
+ this.content.padding = value;
60488
+ this.requestRender();
60489
+ }
60490
+ set paddingX(value) {
60491
+ this.content.paddingX = value;
60492
+ this.requestRender();
60493
+ }
60494
+ set paddingY(value) {
60495
+ this.content.paddingY = value;
60496
+ this.requestRender();
60497
+ }
60498
+ set paddingTop(value) {
60499
+ this.content.paddingTop = value;
60500
+ this.requestRender();
60501
+ }
60502
+ set paddingRight(value) {
60503
+ this.content.paddingRight = value;
60504
+ this.requestRender();
60505
+ }
60506
+ set paddingBottom(value) {
60507
+ this.content.paddingBottom = value;
60508
+ this.requestRender();
60509
+ }
60510
+ set paddingLeft(value) {
60511
+ this.content.paddingLeft = value;
60512
+ this.requestRender();
60513
+ }
60824
60514
  set rootOptions(options) {
60825
60515
  Object.assign(this, options);
60826
60516
  this.requestRender();
@@ -61582,8 +61272,8 @@ class TabSelectRenderable extends Renderable {
61582
61272
  }
61583
61273
  }
61584
61274
 
61585
- // node_modules/@opentui/react/chunk-9gg102mq.js
61586
- init_chunk_eecw9x2f();
61275
+ // node_modules/@opentui/react/chunk-7v2hbtna.js
61276
+ init_chunk_2mx7fq49();
61587
61277
  var import_react = __toESM(require_react(), 1);
61588
61278
  var import_react2 = __toESM(require_react(), 1);
61589
61279
  var import_react3 = __toESM(require_react(), 1);
@@ -61710,7 +61400,7 @@ class ErrorBoundary extends import_react3.default.Component {
61710
61400
  }
61711
61401
  var package_default = {
61712
61402
  name: "@opentui/react",
61713
- version: "0.1.83",
61403
+ version: "0.1.84",
61714
61404
  description: "React renderer for building terminal user interfaces using OpenTUI core",
61715
61405
  license: "MIT",
61716
61406
  repository: {
@@ -62045,7 +61735,7 @@ var hostConfig = {
62045
61735
  var reconciler = import_react_reconciler.default(hostConfig);
62046
61736
  if (process.env["DEV"] === "true") {
62047
61737
  try {
62048
- await init_chunk_pm1hna8x().then(() => exports_chunk_pm1hna8x);
61738
+ await init_chunk_bdqvmfwv().then(() => exports_chunk_bdqvmfwv);
62049
61739
  } catch (error) {
62050
61740
  if (error.code === "ERR_MODULE_NOT_FOUND") {
62051
61741
  console.warn(`
@@ -62090,7 +61780,7 @@ function createRoot(renderer) {
62090
61780
  }
62091
61781
 
62092
61782
  // node_modules/@opentui/react/index.js
62093
- init_chunk_eecw9x2f();
61783
+ init_chunk_2mx7fq49();
62094
61784
  var import_react5 = __toESM(require_react(), 1);
62095
61785
  var import_react6 = __toESM(require_react(), 1);
62096
61786
  var import_react7 = __toESM(require_react(), 1);
@@ -63078,6 +62768,10 @@ function App() {
63078
62768
  // index.jsx
63079
62769
  var jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
63080
62770
  async function main2() {
62771
+ if (process.env.APEX_LOCAL_SERVER === "1") {
62772
+ const { startServer } = await Promise.resolve().then(() => __toESM(require_server(), 1));
62773
+ await startServer();
62774
+ }
63081
62775
  const renderer = await createCliRenderer({
63082
62776
  useAlternateScreen: true,
63083
62777
  exitOnCtrlC: false,