numbl 0.0.15 → 0.0.16

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-cli/cli.js CHANGED
@@ -158,17 +158,17 @@ async function fetchPackageIndex(backend, indexUrl = DEFAULT_INDEX_URL) {
158
158
  return backend.fetchJson(indexUrl);
159
159
  }
160
160
  function findPackageEntry(index2, packageName, arch) {
161
- const exact = index2.packages.find(
162
- (p) => p.name === packageName && p.architecture === arch
163
- );
164
- if (exact) return exact;
165
- return index2.packages.find(
166
- (p) => p.name === packageName && p.architecture === "any"
167
- );
161
+ for (const candidate of ["numbl_" + arch, "numbl_wasm", "all"]) {
162
+ const entry = index2.packages.find(
163
+ (p) => p.name === packageName && p.architecture === candidate
164
+ );
165
+ if (entry) return entry;
166
+ }
167
+ return void 0;
168
168
  }
169
169
  function listAvailablePackages(index2, arch) {
170
170
  return index2.packages.filter(
171
- (p) => p.architecture === arch || p.architecture === "any"
171
+ (p) => p.architecture === arch || p.architecture === "wasm" || p.architecture === "all"
172
172
  );
173
173
  }
174
174
 
@@ -181,7 +181,9 @@ function resolveDependencies(index2, packageName, arch) {
181
181
  visited.add(name);
182
182
  const entry = findPackageEntry(index2, name, arch);
183
183
  if (!entry) {
184
- throw new Error(`Package "${name}" not found for architecture "${arch}"`);
184
+ throw new Error(
185
+ `Package "${name}" not found for architecture "${arch}" (tried ${arch}, wasm, all)`
186
+ );
185
187
  }
186
188
  for (const dep of entry.dependencies) {
187
189
  visit(dep);
@@ -210,13 +212,13 @@ function computeRequiredPackages(directlyInstalled, index2, arch) {
210
212
 
211
213
  // src/mip/mip-manager.ts
212
214
  function packagesDir(mipDir) {
213
- return `${mipDir}/packages`;
215
+ return `${mipDir}/numbl_packages`;
214
216
  }
215
217
  function packageDir(mipDir, name) {
216
- return `${mipDir}/packages/${name}`;
218
+ return `${mipDir}/numbl_packages/${name}`;
217
219
  }
218
220
  function directlyInstalledPath(mipDir) {
219
- return `${mipDir}/packages/directly_installed.txt`;
221
+ return `${mipDir}/numbl_packages/directly_installed.txt`;
220
222
  }
221
223
  var MipManager = class {
222
224
  constructor(backend) {
@@ -17600,6 +17602,22 @@ function complexComparisonOp(a, b, op) {
17600
17602
  `Matrix dimensions must agree for comparison: [${at.shape.join(",")}] vs [${bt.shape.join(",")}]`
17601
17603
  );
17602
17604
  }
17605
+ function signedInf(x) {
17606
+ return x > 0 ? Infinity : x < 0 ? -Infinity : 0;
17607
+ }
17608
+ function complexDivide(aRe, aIm, bRe, bIm) {
17609
+ const denom = bRe * bRe + bIm * bIm;
17610
+ if (denom === 0) {
17611
+ if (aRe === 0 && aIm === 0) {
17612
+ return { re: NaN, im: 0 };
17613
+ }
17614
+ return { re: signedInf(aRe), im: signedInf(aIm) };
17615
+ }
17616
+ return {
17617
+ re: (aRe * bRe + aIm * bIm) / denom,
17618
+ im: (aIm * bRe - aRe * bIm) / denom
17619
+ };
17620
+ }
17603
17621
  function complexBinaryOp(a, b, op) {
17604
17622
  const ac = toComplexParts(a);
17605
17623
  const bc = toComplexParts(b);
@@ -17702,25 +17720,13 @@ function mDiv(a, b) {
17702
17720
  return mConjugateTranspose(result);
17703
17721
  }
17704
17722
  if (isComplexOrMixed(a, b)) {
17705
- return complexBinaryOp(a, b, (aRe, aIm, bRe, bIm) => {
17706
- const denom = bRe * bRe + bIm * bIm;
17707
- return {
17708
- re: (aRe * bRe + aIm * bIm) / denom,
17709
- im: (aIm * bRe - aRe * bIm) / denom
17710
- };
17711
- });
17723
+ return complexBinaryOp(a, b, complexDivide);
17712
17724
  }
17713
17725
  return binaryOp(a, b, (x, y) => x / y);
17714
17726
  }
17715
17727
  function mElemDiv(a, b) {
17716
17728
  if (isComplexOrMixed(a, b)) {
17717
- return complexBinaryOp(a, b, (aRe, aIm, bRe, bIm) => {
17718
- const denom = bRe * bRe + bIm * bIm;
17719
- return {
17720
- re: (aRe * bRe + aIm * bIm) / denom,
17721
- im: (aIm * bRe - aRe * bIm) / denom
17722
- };
17723
- });
17729
+ return complexBinaryOp(a, b, complexDivide);
17724
17730
  }
17725
17731
  return binaryOp(a, b, (x, y) => x / y);
17726
17732
  }
@@ -20603,7 +20609,8 @@ var COMMAND_VERBS = [
20603
20609
  "square",
20604
20610
  "vis3d"
20605
20611
  ],
20606
- optional: false
20612
+ optional: false,
20613
+ multiKeyword: true
20607
20614
  }
20608
20615
  },
20609
20616
  { name: "clear", argKind: { type: "Any" } },
@@ -20965,19 +20972,41 @@ var ExpressionParser = class extends ParserBase {
20965
20972
  }
20966
20973
  }
20967
20974
  parsePow() {
20968
- const node = this.parsePostfix();
20969
- const tok = this.peekToken();
20970
- let op;
20971
- if (tok === 36 /* Caret */) {
20972
- op = "Pow" /* Pow */;
20973
- } else if (tok === 58 /* DotCaret */) {
20974
- op = "ElemPow" /* ElemPow */;
20975
- } else {
20976
- return node;
20975
+ let node = this.parsePostfix();
20976
+ while (true) {
20977
+ const tok = this.peekToken();
20978
+ let op;
20979
+ if (tok === 36 /* Caret */) {
20980
+ op = "Pow" /* Pow */;
20981
+ } else if (tok === 58 /* DotCaret */) {
20982
+ op = "ElemPow" /* ElemPow */;
20983
+ } else {
20984
+ return node;
20985
+ }
20986
+ this.pos++;
20987
+ const rhs = this.parsePowRHS();
20988
+ node = this.makeBinary(node, op, rhs);
20989
+ }
20990
+ }
20991
+ /** Parse the right-hand side of a ^ or .^ operator: unary prefixes then postfix. */
20992
+ parsePowRHS() {
20993
+ if (this.peekToken() === 31 /* Plus */) {
20994
+ const start = this.tokens[this.pos].position;
20995
+ this.pos++;
20996
+ const expr = this.parsePowRHS();
20997
+ return this.makeUnary("Plus" /* Plus */, expr, start);
20998
+ } else if (this.peekToken() === 32 /* Minus */) {
20999
+ const start = this.tokens[this.pos].position;
21000
+ this.pos++;
21001
+ const expr = this.parsePowRHS();
21002
+ return this.makeUnary("Minus" /* Minus */, expr, start);
21003
+ } else if (this.peekToken() === 39 /* Tilde */) {
21004
+ const start = this.tokens[this.pos].position;
21005
+ this.pos++;
21006
+ const expr = this.parsePowRHS();
21007
+ return this.makeUnary("Not" /* Not */, expr, start);
20977
21008
  }
20978
- this.pos++;
20979
- const rhs = this.parseUnary();
20980
- return this.makeBinary(node, op, rhs);
21009
+ return this.parsePostfix();
20981
21010
  }
20982
21011
  parsePostfixWithBase(expr) {
20983
21012
  while (true) {
@@ -21560,25 +21589,32 @@ var CommandParser = class extends ExpressionParser {
21560
21589
  }
21561
21590
  return args;
21562
21591
  }
21563
- if (args.length > 1) {
21592
+ if (args.length > 1 && !command.argKind.multiKeyword) {
21564
21593
  throw this.error(
21565
21594
  `'${command.name}' command syntax accepts only one argument`
21566
21595
  );
21567
21596
  }
21568
- const keyword = extractKeyword(args[0]);
21569
- if (!keyword) {
21570
- throw this.error(
21571
- `'${command.name}' command syntax expects a keyword argument`
21572
- );
21597
+ const keywords = [];
21598
+ for (const arg of args) {
21599
+ const keyword = extractKeyword(arg);
21600
+ if (!keyword) {
21601
+ throw this.error(
21602
+ `'${command.name}' command syntax expects a keyword argument`
21603
+ );
21604
+ }
21605
+ if (allowed !== void 0 && !allowed.some((a) => a.toLowerCase() === keyword.toLowerCase())) {
21606
+ throw this.error(
21607
+ `'${command.name}' command syntax does not support '${keyword}'`
21608
+ );
21609
+ }
21610
+ keywords.push(keyword);
21573
21611
  }
21574
- if (allowed === void 0 || allowed.some((a) => a.toLowerCase() === keyword.toLowerCase())) {
21575
- const span = args[0].span;
21576
- return [{ type: "String", value: `"${keyword}"`, span }];
21577
- } else {
21578
- throw this.error(
21579
- `'${command.name}' command syntax does not support '${keyword}'`
21580
- );
21612
+ if (keywords.length === 1) {
21613
+ const span2 = args[0].span;
21614
+ return [{ type: "String", value: `"${keywords[0]}"`, span: span2 }];
21581
21615
  }
21616
+ const span = args[0].span;
21617
+ return [{ type: "String", value: `"${keywords.join(" ")}"`, span }];
21582
21618
  }
21583
21619
  return args;
21584
21620
  }
@@ -33809,6 +33845,12 @@ function registerMiscFunctions() {
33809
33845
  return RTV.num(0);
33810
33846
  })
33811
33847
  );
33848
+ register(
33849
+ "clc",
33850
+ builtinSingle(() => {
33851
+ return RTV.num(0);
33852
+ })
33853
+ );
33812
33854
  register(
33813
33855
  "clf",
33814
33856
  builtinSingle(() => {
@@ -34257,6 +34299,62 @@ function registerGraphicsFunctions() {
34257
34299
  "shading",
34258
34300
  builtinSingle(() => RTV.num(0))
34259
34301
  );
34302
+ register(
34303
+ "subplot",
34304
+ builtinSingle(() => RTV.num(0))
34305
+ );
34306
+ register(
34307
+ "legend",
34308
+ builtinSingle(() => RTV.num(0))
34309
+ );
34310
+ register(
34311
+ "sgtitle",
34312
+ builtinSingle(() => RTV.num(0))
34313
+ );
34314
+ register(
34315
+ "zlabel",
34316
+ builtinSingle(() => RTV.num(0))
34317
+ );
34318
+ register(
34319
+ "colorbar",
34320
+ builtinSingle(() => RTV.num(0))
34321
+ );
34322
+ register(
34323
+ "colormap",
34324
+ builtinSingle(() => RTV.num(0))
34325
+ );
34326
+ register(
34327
+ "axis",
34328
+ builtinSingle(() => RTV.num(0))
34329
+ );
34330
+ register(
34331
+ "view",
34332
+ builtinSingle(() => RTV.num(0))
34333
+ );
34334
+ register(
34335
+ "imagesc",
34336
+ builtinSingle(() => RTV.num(0))
34337
+ );
34338
+ register(
34339
+ "contour",
34340
+ builtinSingle(() => RTV.num(0))
34341
+ );
34342
+ register(
34343
+ "contourf",
34344
+ builtinSingle(() => RTV.num(0))
34345
+ );
34346
+ register(
34347
+ "mesh",
34348
+ builtinSingle(() => RTV.num(0))
34349
+ );
34350
+ register(
34351
+ "waterfall",
34352
+ builtinSingle(() => RTV.num(0))
34353
+ );
34354
+ register(
34355
+ "scatter",
34356
+ builtinSingle(() => RTV.num(0))
34357
+ );
34260
34358
  register(
34261
34359
  "drawnow",
34262
34360
  builtinSingle(() => RTV.num(0))
@@ -34265,6 +34363,45 @@ function registerGraphicsFunctions() {
34265
34363
  "pause",
34266
34364
  builtinSingle(() => RTV.num(0))
34267
34365
  );
34366
+ const colormapNames = [
34367
+ "parula",
34368
+ "jet",
34369
+ "hsv",
34370
+ "hot",
34371
+ "cool",
34372
+ "spring",
34373
+ "summer",
34374
+ "autumn",
34375
+ "winter",
34376
+ "gray",
34377
+ "bone",
34378
+ "copper",
34379
+ "pink"
34380
+ ];
34381
+ for (const cm of colormapNames) {
34382
+ register(
34383
+ cm,
34384
+ builtinSingle(() => RTV.char(cm))
34385
+ );
34386
+ }
34387
+ register(
34388
+ "peaks",
34389
+ builtinSingle((args) => {
34390
+ const n = args.length > 0 ? isRuntimeNumber(args[0]) ? args[0] : toNumber(args[0]) : 49;
34391
+ const data = new FloatXArray(n * n);
34392
+ for (let j = 0; j < n; j++) {
34393
+ const y = -3 + 6 * j / (n - 1);
34394
+ for (let i = 0; i < n; i++) {
34395
+ const x = -3 + 6 * i / (n - 1);
34396
+ const x2 = x * x;
34397
+ const y2 = y * y;
34398
+ const z = 3 * Math.pow(1 - x, 2) * Math.exp(-x2 - Math.pow(y + 1, 2)) - 10 * (x / 5 - x * x2 - Math.pow(y, 5)) * Math.exp(-x2 - y2) - 1 / 3 * Math.exp(-Math.pow(x + 1, 2) - y2);
34399
+ data[j * n + i] = z;
34400
+ }
34401
+ }
34402
+ return RTV.tensor(data, [n, n]);
34403
+ })
34404
+ );
34268
34405
  }
34269
34406
 
34270
34407
  // src/numbl-core/builtins/validators.ts
@@ -34436,7 +34573,7 @@ function registerDummyStringFunctions() {
34436
34573
  register(name, fn);
34437
34574
  }
34438
34575
  }
34439
- var returnEmptyArrayFunctions = ["who", "xlim", "ylim", "jet", "hot"];
34576
+ var returnEmptyArrayFunctions = ["who", "xlim", "ylim"];
34440
34577
  function registerDummyArrayFunctions() {
34441
34578
  const fn = builtinSingle(() => RTV.tensor([], [0, 0]), {
34442
34579
  outputType: IType.tensor()
@@ -36298,6 +36435,30 @@ function dispatch(rt, name, nargout, args, targetClassName) {
36298
36435
  if (name === "surf") {
36299
36436
  return rt.surf_call(args.map((a) => ensureRuntimeValue(a)));
36300
36437
  }
36438
+ if (name === "scatter") {
36439
+ return rt.scatter_call(args.map((a) => ensureRuntimeValue(a)));
36440
+ }
36441
+ if (name === "imagesc") {
36442
+ return rt.imagesc_call(args.map((a) => ensureRuntimeValue(a)));
36443
+ }
36444
+ if (name === "contour") {
36445
+ return rt.contour_call(
36446
+ args.map((a) => ensureRuntimeValue(a)),
36447
+ false
36448
+ );
36449
+ }
36450
+ if (name === "contourf") {
36451
+ return rt.contour_call(
36452
+ args.map((a) => ensureRuntimeValue(a)),
36453
+ true
36454
+ );
36455
+ }
36456
+ if (name === "mesh") {
36457
+ return rt.mesh_call(args.map((a) => ensureRuntimeValue(a)));
36458
+ }
36459
+ if (name === "waterfall") {
36460
+ return rt.mesh_call(args.map((a) => ensureRuntimeValue(a)));
36461
+ }
36301
36462
  }
36302
36463
  if (rt.compileSpecialized) {
36303
36464
  const argTypes = args.map(
@@ -36345,6 +36506,30 @@ function callBuiltin(rt, name, nargout, args) {
36345
36506
  if (name === "surf") {
36346
36507
  return rt.surf_call(args.map((a) => ensureRuntimeValue(a)));
36347
36508
  }
36509
+ if (name === "scatter") {
36510
+ return rt.scatter_call(args.map((a) => ensureRuntimeValue(a)));
36511
+ }
36512
+ if (name === "imagesc") {
36513
+ return rt.imagesc_call(args.map((a) => ensureRuntimeValue(a)));
36514
+ }
36515
+ if (name === "contour") {
36516
+ return rt.contour_call(
36517
+ args.map((a) => ensureRuntimeValue(a)),
36518
+ false
36519
+ );
36520
+ }
36521
+ if (name === "contourf") {
36522
+ return rt.contour_call(
36523
+ args.map((a) => ensureRuntimeValue(a)),
36524
+ true
36525
+ );
36526
+ }
36527
+ if (name === "mesh") {
36528
+ return rt.mesh_call(args.map((a) => ensureRuntimeValue(a)));
36529
+ }
36530
+ if (name === "waterfall") {
36531
+ return rt.mesh_call(args.map((a) => ensureRuntimeValue(a)));
36532
+ }
36348
36533
  const builtin = rt.builtins[name];
36349
36534
  if (builtin) return builtin(nargout, args);
36350
36535
  throw new RuntimeError(`'${name}' is not a builtin function`);
@@ -36359,6 +36544,30 @@ function callBuiltinSync(rt, name, nargout, args) {
36359
36544
  if (name === "surf") {
36360
36545
  return rt.surf_call(args.map((a) => ensureRuntimeValue(a)));
36361
36546
  }
36547
+ if (name === "scatter") {
36548
+ return rt.scatter_call(args.map((a) => ensureRuntimeValue(a)));
36549
+ }
36550
+ if (name === "imagesc") {
36551
+ return rt.imagesc_call(args.map((a) => ensureRuntimeValue(a)));
36552
+ }
36553
+ if (name === "contour") {
36554
+ return rt.contour_call(
36555
+ args.map((a) => ensureRuntimeValue(a)),
36556
+ false
36557
+ );
36558
+ }
36559
+ if (name === "contourf") {
36560
+ return rt.contour_call(
36561
+ args.map((a) => ensureRuntimeValue(a)),
36562
+ true
36563
+ );
36564
+ }
36565
+ if (name === "mesh") {
36566
+ return rt.mesh_call(args.map((a) => ensureRuntimeValue(a)));
36567
+ }
36568
+ if (name === "waterfall") {
36569
+ return rt.mesh_call(args.map((a) => ensureRuntimeValue(a)));
36570
+ }
36362
36571
  const builtin = rt.builtins[name];
36363
36572
  if (builtin) return builtin(nargout, args);
36364
36573
  throw new RuntimeError(`'${name}' is not a builtin function`);
@@ -38238,6 +38447,88 @@ function getStringValueIfString(v) {
38238
38447
  if (isRuntimeChar(v)) return v.value;
38239
38448
  return void 0;
38240
38449
  }
38450
+ function parseScatterArgs(args) {
38451
+ if (args.length < 2) throw new Error("scatter requires at least 2 arguments");
38452
+ const xData = toNumberArray(args[0]);
38453
+ const yData = toNumberArray(args[1]);
38454
+ const trace = {
38455
+ x: xData,
38456
+ y: yData,
38457
+ marker: "o",
38458
+ lineStyle: "none"
38459
+ };
38460
+ let pos = 2;
38461
+ let filled = false;
38462
+ if (pos < args.length && isNumericArg(args[pos])) {
38463
+ const sz = args[pos];
38464
+ if (isRuntimeNumber(sz)) {
38465
+ trace.markerSize = Math.sqrt(sz) * 0.5;
38466
+ } else if (isRuntimeTensor(sz)) {
38467
+ const sArr = toNumberArray(sz);
38468
+ if (sArr.length === 1 || new Set(sArr).size === 1) {
38469
+ trace.markerSize = Math.sqrt(sArr[0]) * 0.5;
38470
+ }
38471
+ }
38472
+ pos++;
38473
+ }
38474
+ if (pos < args.length && !isNameValueKey(args[pos])) {
38475
+ if (isStringArg(args[pos])) {
38476
+ const s = getStringValue(args[pos]);
38477
+ if (s === "filled") {
38478
+ filled = true;
38479
+ pos++;
38480
+ } else {
38481
+ const c = resolveColor(s);
38482
+ if (c) {
38483
+ trace.color = c;
38484
+ pos++;
38485
+ } else {
38486
+ const spec = parseLineSpec(s);
38487
+ if (spec?.marker) {
38488
+ trace.marker = spec.marker;
38489
+ if (spec.color) trace.color = COLOR_SHORT[spec.color];
38490
+ pos++;
38491
+ }
38492
+ }
38493
+ }
38494
+ } else if (isNumericArg(args[pos])) {
38495
+ const c = resolveColor(args[pos]);
38496
+ if (c) {
38497
+ trace.color = c;
38498
+ pos++;
38499
+ }
38500
+ }
38501
+ }
38502
+ while (pos < args.length && isStringArg(args[pos]) && !isNameValueKey(args[pos])) {
38503
+ const s = getStringValue(args[pos]);
38504
+ if (s === "filled") {
38505
+ filled = true;
38506
+ pos++;
38507
+ } else {
38508
+ const spec = parseLineSpec(s);
38509
+ if (spec?.marker) {
38510
+ trace.marker = spec.marker;
38511
+ if (spec.color) trace.color = COLOR_SHORT[spec.color];
38512
+ pos++;
38513
+ } else {
38514
+ break;
38515
+ }
38516
+ }
38517
+ }
38518
+ if (filled) {
38519
+ trace.markerFaceColor = trace.color || [0, 0, 1];
38520
+ }
38521
+ while (pos < args.length) {
38522
+ const key = isNameValueKey(args[pos]);
38523
+ if (!key) break;
38524
+ pos++;
38525
+ if (pos >= args.length) break;
38526
+ const value = args[pos];
38527
+ pos++;
38528
+ applyNameValue([trace], key, value);
38529
+ }
38530
+ return [trace];
38531
+ }
38241
38532
  function applyNameValue(traces, key, value) {
38242
38533
  switch (key) {
38243
38534
  case "color": {
@@ -38282,6 +38573,95 @@ function applyNameValue(traces, key, value) {
38282
38573
  }
38283
38574
  }
38284
38575
  }
38576
+ function parseImagescArgs(args) {
38577
+ if (args.length === 1) {
38578
+ const info = getMatrixInfo(args[0]);
38579
+ return {
38580
+ x: [1, info.cols],
38581
+ y: [1, info.rows],
38582
+ z: info.data,
38583
+ rows: info.rows,
38584
+ cols: info.cols
38585
+ };
38586
+ }
38587
+ if (args.length >= 3) {
38588
+ const xArr = toNumberArray(args[0]);
38589
+ const yArr = toNumberArray(args[1]);
38590
+ const info = getMatrixInfo(args[2]);
38591
+ return {
38592
+ x: [xArr[0], xArr[xArr.length - 1]],
38593
+ y: [yArr[0], yArr[yArr.length - 1]],
38594
+ z: info.data,
38595
+ rows: info.rows,
38596
+ cols: info.cols
38597
+ };
38598
+ }
38599
+ throw new Error("imagesc requires 1 or 3+ arguments");
38600
+ }
38601
+ function parseContourArgs(args, filled) {
38602
+ let pos = 0;
38603
+ let numericCount = 0;
38604
+ for (let i = pos; i < args.length; i++) {
38605
+ if (isNumericArg(args[i])) numericCount++;
38606
+ else break;
38607
+ }
38608
+ let xData;
38609
+ let yData;
38610
+ let zData;
38611
+ let rows;
38612
+ let cols;
38613
+ let nLevels = 10;
38614
+ if (numericCount === 1) {
38615
+ const info = getMatrixInfo(args[pos++]);
38616
+ rows = info.rows;
38617
+ cols = info.cols;
38618
+ zData = info.data;
38619
+ const gen = generateMeshgrid(rows, cols);
38620
+ xData = gen.x;
38621
+ yData = gen.y;
38622
+ } else if (numericCount === 2) {
38623
+ const info = getMatrixInfo(args[pos++]);
38624
+ rows = info.rows;
38625
+ cols = info.cols;
38626
+ zData = info.data;
38627
+ nLevels = typeof args[pos] === "number" ? args[pos] : toNumber(args[pos]);
38628
+ pos++;
38629
+ const gen = generateMeshgrid(rows, cols);
38630
+ xData = gen.x;
38631
+ yData = gen.y;
38632
+ } else if (numericCount === 3) {
38633
+ const x = args[pos++];
38634
+ const y = args[pos++];
38635
+ const zInfo = getMatrixInfo(args[pos++]);
38636
+ rows = zInfo.rows;
38637
+ cols = zInfo.cols;
38638
+ zData = zInfo.data;
38639
+ const expanded = expandXY(x, y, rows, cols);
38640
+ xData = expanded.x;
38641
+ yData = expanded.y;
38642
+ } else if (numericCount >= 4) {
38643
+ const x = args[pos++];
38644
+ const y = args[pos++];
38645
+ const zInfo = getMatrixInfo(args[pos++]);
38646
+ rows = zInfo.rows;
38647
+ cols = zInfo.cols;
38648
+ zData = zInfo.data;
38649
+ nLevels = typeof args[pos] === "number" ? args[pos] : toNumber(args[pos]);
38650
+ pos++;
38651
+ const expanded = expandXY(x, y, rows, cols);
38652
+ xData = expanded.x;
38653
+ yData = expanded.y;
38654
+ } else {
38655
+ throw new Error("contour requires at least 1 argument");
38656
+ }
38657
+ return { x: xData, y: yData, z: zData, rows, cols, nLevels, filled };
38658
+ }
38659
+ function parseMeshArgs(args) {
38660
+ const trace = parseSurfArgs(args);
38661
+ if (!trace.edgeColor) trace.edgeColor = "flat";
38662
+ if (!trace.faceColor) trace.faceColor = "none";
38663
+ return trace;
38664
+ }
38285
38665
 
38286
38666
  // src/numbl-core/runtime/syncChannel.ts
38287
38667
  var syncSleepWarned = false;
@@ -38307,10 +38687,17 @@ function syncSleep(ms) {
38307
38687
  // src/numbl-core/runtime/runtimePlot.ts
38308
38688
  function plotInstr(plotInstructions, instr) {
38309
38689
  if (instr.type === "set_figure_handle") {
38310
- plotInstructions.push({
38311
- type: "set_figure_handle",
38312
- handle: typeof instr.handle === "number" ? instr.handle : toNumber(ensureRuntimeValue(instr.handle))
38313
- });
38690
+ let handle;
38691
+ if (typeof instr.handle === "number") {
38692
+ handle = instr.handle;
38693
+ } else {
38694
+ try {
38695
+ handle = toNumber(ensureRuntimeValue(instr.handle));
38696
+ } catch {
38697
+ handle = 1;
38698
+ }
38699
+ }
38700
+ plotInstructions.push({ type: "set_figure_handle", handle });
38314
38701
  } else if (instr.type === "plot") {
38315
38702
  plotInstructions.push({
38316
38703
  type: "plot",
@@ -38349,7 +38736,63 @@ function plotInstr(plotInstructions, instr) {
38349
38736
  plotInstructions.push({ type: "close_all" });
38350
38737
  } else if (instr.type === "clf") {
38351
38738
  plotInstructions.push({ type: "clf" });
38739
+ } else if (instr.type === "set_subplot") {
38740
+ const rows = typeof instr.rows === "number" ? instr.rows : toNumber(ensureRuntimeValue(instr.rows));
38741
+ const cols = typeof instr.cols === "number" ? instr.cols : toNumber(ensureRuntimeValue(instr.cols));
38742
+ const index2 = typeof instr.index === "number" ? instr.index : toNumber(ensureRuntimeValue(instr.index));
38743
+ plotInstructions.push({ type: "set_subplot", rows, cols, index: index2 });
38744
+ } else if (instr.type === "set_sgtitle") {
38745
+ const text = typeof instr.text === "string" ? instr.text : toString(ensureRuntimeValue(instr.text));
38746
+ plotInstructions.push({ type: "set_sgtitle", text });
38747
+ } else if (instr.type === "set_grid") {
38748
+ const val = instr.value;
38749
+ let on;
38750
+ if (typeof val === "string") on = val === "on";
38751
+ else if (typeof val === "boolean") on = val;
38752
+ else {
38753
+ const mv = ensureRuntimeValue(val);
38754
+ on = toString(mv) === "on";
38755
+ }
38756
+ plotInstructions.push({ type: "set_grid", value: on });
38757
+ } else if (instr.type === "set_zlabel") {
38758
+ const text = typeof instr.text === "string" ? instr.text : toString(ensureRuntimeValue(instr.text));
38759
+ plotInstructions.push({ type: "set_zlabel", text });
38760
+ } else if (instr.type === "set_colorbar") {
38761
+ const val = typeof instr.value === "string" ? instr.value : toString(ensureRuntimeValue(instr.value));
38762
+ plotInstructions.push({ type: "set_colorbar", value: val });
38763
+ } else if (instr.type === "set_colormap") {
38764
+ const name = typeof instr.name === "string" ? instr.name : toString(ensureRuntimeValue(instr.name));
38765
+ plotInstructions.push({
38766
+ type: "set_colormap",
38767
+ name: name.replace(/^"|"$/g, "")
38768
+ });
38769
+ } else if (instr.type === "set_axis") {
38770
+ const val = typeof instr.value === "string" ? instr.value : toString(ensureRuntimeValue(instr.value));
38771
+ plotInstructions.push({
38772
+ type: "set_axis",
38773
+ value: val.replace(/^"|"$/g, "")
38774
+ });
38775
+ }
38776
+ }
38777
+ function viewCall(plotInstructions, args) {
38778
+ let az;
38779
+ let el;
38780
+ if (args.length === 1) {
38781
+ const n = typeof args[0] === "number" ? args[0] : toNumber(args[0]);
38782
+ if (n === 2) {
38783
+ az = 0;
38784
+ el = 90;
38785
+ } else {
38786
+ az = -37.5;
38787
+ el = 30;
38788
+ }
38789
+ } else if (args.length >= 2) {
38790
+ az = typeof args[0] === "number" ? args[0] : toNumber(args[0]);
38791
+ el = typeof args[1] === "number" ? args[1] : toNumber(args[1]);
38792
+ } else {
38793
+ return;
38352
38794
  }
38795
+ plotInstructions.push({ type: "set_view", az, el });
38353
38796
  }
38354
38797
  function plotCall(plotInstructions, args) {
38355
38798
  const traces = parsePlotArgs(args);
@@ -38367,6 +38810,38 @@ function surfCall(plotInstructions, args) {
38367
38810
  const trace = parseSurfArgs(args);
38368
38811
  plotInstructions.push({ type: "surf", trace });
38369
38812
  }
38813
+ function imagescCall(plotInstructions, args) {
38814
+ const trace = parseImagescArgs(args);
38815
+ plotInstructions.push({ type: "imagesc", trace });
38816
+ }
38817
+ function contourCall(plotInstructions, args, filled) {
38818
+ const trace = parseContourArgs(args, filled);
38819
+ plotInstructions.push({ type: "contour", trace });
38820
+ }
38821
+ function meshCall(plotInstructions, args) {
38822
+ const trace = parseMeshArgs(args);
38823
+ plotInstructions.push({ type: "mesh", trace });
38824
+ }
38825
+ function scatterCall(plotInstructions, args) {
38826
+ const traces = parseScatterArgs(args);
38827
+ if (traces.length > 0) {
38828
+ plotInstructions.push({ type: "plot", traces });
38829
+ }
38830
+ }
38831
+ function legendCall(plotInstructions, args) {
38832
+ const labels = [];
38833
+ for (let i = 0; i < args.length; i++) {
38834
+ const s = toString(args[i]);
38835
+ if (s === "Location" || s === "Orientation" || s === "FontSize" || s === "Box" || s === "Color" || s === "EdgeColor" || s === "TextColor") {
38836
+ i++;
38837
+ continue;
38838
+ }
38839
+ labels.push(s);
38840
+ }
38841
+ if (labels.length > 0) {
38842
+ plotInstructions.push({ type: "set_legend", labels });
38843
+ }
38844
+ }
38370
38845
  function drawnow(plotInstructions, options) {
38371
38846
  if (options.onDrawnow && plotInstructions.length > 0) {
38372
38847
  options.onDrawnow([...plotInstructions]);
@@ -38475,6 +38950,61 @@ var Runtime = class _Runtime {
38475
38950
  this.builtins["surf"] = (_nargout, args) => {
38476
38951
  this.surf_call(args.map((a) => ensureRuntimeValue(a)));
38477
38952
  };
38953
+ this.builtins["scatter"] = (_nargout, args) => {
38954
+ this.scatter_call(args.map((a) => ensureRuntimeValue(a)));
38955
+ };
38956
+ this.builtins["imagesc"] = (_nargout, args) => {
38957
+ this.imagesc_call(args.map((a) => ensureRuntimeValue(a)));
38958
+ };
38959
+ this.builtins["contour"] = (_nargout, args) => {
38960
+ this.contour_call(
38961
+ args.map((a) => ensureRuntimeValue(a)),
38962
+ false
38963
+ );
38964
+ };
38965
+ this.builtins["contourf"] = (_nargout, args) => {
38966
+ this.contour_call(
38967
+ args.map((a) => ensureRuntimeValue(a)),
38968
+ true
38969
+ );
38970
+ };
38971
+ this.builtins["mesh"] = (_nargout, args) => {
38972
+ this.mesh_call(args.map((a) => ensureRuntimeValue(a)));
38973
+ };
38974
+ this.builtins["waterfall"] = (_nargout, args) => {
38975
+ this.mesh_call(args.map((a) => ensureRuntimeValue(a)));
38976
+ };
38977
+ this.builtins["colormap"] = (_nargout, args) => {
38978
+ if (args.length > 0) {
38979
+ const rv = ensureRuntimeValue(args[0]);
38980
+ const name = toString(rv).replace(/^"|"$/g, "");
38981
+ plotInstr(this.plotInstructions, { type: "set_colormap", name });
38982
+ }
38983
+ };
38984
+ this.builtins["view"] = (_nargout, args) => {
38985
+ this.view_call(args.map((a) => ensureRuntimeValue(a)));
38986
+ };
38987
+ this.builtins["zlabel"] = (_nargout, args) => {
38988
+ if (args.length > 0) {
38989
+ plotInstr(this.plotInstructions, {
38990
+ type: "set_zlabel",
38991
+ text: args[0]
38992
+ });
38993
+ }
38994
+ };
38995
+ this.builtins["colorbar"] = (_nargout, args) => {
38996
+ const val = args.length > 0 ? toString(ensureRuntimeValue(args[0])) : "on";
38997
+ plotInstr(this.plotInstructions, { type: "set_colorbar", value: val });
38998
+ };
38999
+ this.builtins["axis"] = (_nargout, args) => {
39000
+ if (args.length > 0) {
39001
+ const val = toString(ensureRuntimeValue(args[0])).replace(
39002
+ /^"|"$/g,
39003
+ ""
39004
+ );
39005
+ plotInstr(this.plotInstructions, { type: "set_axis", value: val });
39006
+ }
39007
+ };
38478
39008
  }
38479
39009
  profileEnter(key) {
38480
39010
  if (!this.profilingEnabled) return;
@@ -39065,6 +39595,24 @@ var Runtime = class _Runtime {
39065
39595
  surf_call(args) {
39066
39596
  surfCall(this.plotInstructions, args);
39067
39597
  }
39598
+ scatter_call(args) {
39599
+ scatterCall(this.plotInstructions, args);
39600
+ }
39601
+ imagesc_call(args) {
39602
+ imagescCall(this.plotInstructions, args);
39603
+ }
39604
+ contour_call(args, filled) {
39605
+ contourCall(this.plotInstructions, args, filled);
39606
+ }
39607
+ mesh_call(args) {
39608
+ meshCall(this.plotInstructions, args);
39609
+ }
39610
+ view_call(args) {
39611
+ viewCall(this.plotInstructions, args);
39612
+ }
39613
+ legend_call(args) {
39614
+ legendCall(this.plotInstructions, args);
39615
+ }
39068
39616
  // ── Drawnow / Pause ─────────────────────────────────────────────────
39069
39617
  drawnow() {
39070
39618
  return drawnow(this.plotInstructions, this.options);
@@ -40637,13 +41185,6 @@ var LoweringContext = class _LoweringContext {
40637
41185
  }
40638
41186
  for (const [className, group] of classFolderGroups) {
40639
41187
  if (!group.classDefFile) {
40640
- for (const mf of group.methodFiles) {
40641
- const baseName = mf.name.split("/").pop().replace(/\.m$/, "");
40642
- this.registry.filesByFuncName.set(baseName, {
40643
- fileName: mf.name,
40644
- source: mf.source
40645
- });
40646
- }
40647
41188
  continue;
40648
41189
  }
40649
41190
  this.registerWorkspaceClass(className, group.classDefFile);
@@ -40778,7 +41319,9 @@ var LoweringContext = class _LoweringContext {
40778
41319
  file.name,
40779
41320
  file.source
40780
41321
  );
40781
- this.registry.classesByName.set(qualifiedName, info);
41322
+ if (!this.registry.classesByName.has(qualifiedName)) {
41323
+ this.registry.classesByName.set(qualifiedName, info);
41324
+ }
40782
41325
  }
40783
41326
  /**
40784
41327
  * Register a classdef statement found in the local (main) file.
@@ -41895,6 +42438,22 @@ function genFuncCall(cg, kind) {
41895
42438
  }
41896
42439
  return `$rt.plot_instr({type: "close"})`;
41897
42440
  }
42441
+ if (kind.name === "subplot")
42442
+ return `$rt.plot_instr({type: "set_subplot", rows: ${args[0] ?? "1"}, cols: ${args[1] ?? "1"}, index: ${args[2] ?? "1"}})`;
42443
+ if (kind.name === "legend") return `$rt.legend_call([${args.join(", ")}])`;
42444
+ if (kind.name === "sgtitle")
42445
+ return `$rt.plot_instr({type: "set_sgtitle", text: ${args[0] ?? '""'}})`;
42446
+ if (kind.name === "grid")
42447
+ return `$rt.plot_instr({type: "set_grid", value: ${args[0] ?? "true"}})`;
42448
+ if (kind.name === "zlabel")
42449
+ return `$rt.plot_instr({type: "set_zlabel", text: ${args[0] ?? '""'}})`;
42450
+ if (kind.name === "colorbar")
42451
+ return `$rt.plot_instr({type: "set_colorbar", value: ${args[0] ?? '"on"'}})`;
42452
+ if (kind.name === "colormap")
42453
+ return `$rt.plot_instr({type: "set_colormap", name: ${args[0] ?? '"parula"'}})`;
42454
+ if (kind.name === "axis")
42455
+ return `$rt.plot_instr({type: "set_axis", value: ${args[0] ?? '"auto"'}})`;
42456
+ if (kind.name === "view") return `$rt.view_call([${args.join(", ")}])`;
41898
42457
  if (cg.nestedFunctionNames.has(kind.name)) {
41899
42458
  return buildSpecializedCall(
41900
42459
  cg,
@@ -43626,9 +44185,28 @@ function buildWasmMap(wasmFiles) {
43626
44185
  }
43627
44186
  return map;
43628
44187
  }
43629
- function parseWasmDirective(source) {
43630
- const match = source.match(/^\s*\/\/\s*wasm:\s*(\S+)/);
43631
- return match ? match[1] : null;
44188
+ function parseDirectives(source) {
44189
+ const directives = {};
44190
+ const lines = source.split("\n");
44191
+ for (const line of lines) {
44192
+ const match = line.match(/^\s*\/\/\s*(\w+):\s*(\S+)/);
44193
+ if (!match) break;
44194
+ const key = match[1];
44195
+ const value = match[2];
44196
+ if (key === "wasm") directives.wasm = value;
44197
+ else if (key === "native") directives.native = value;
44198
+ }
44199
+ return directives;
44200
+ }
44201
+ function nativeLibFilename(baseName) {
44202
+ switch (process.platform) {
44203
+ case "win32":
44204
+ return `${baseName}.dll`;
44205
+ case "darwin":
44206
+ return `${baseName}.dylib`;
44207
+ default:
44208
+ return `${baseName}.so`;
44209
+ }
43632
44210
  }
43633
44211
  function instantiateWasm(wasmData) {
43634
44212
  const wasmModule = new WebAssembly.Module(wasmData);
@@ -43659,7 +44237,7 @@ function instantiateWasm(wasmData) {
43659
44237
  }
43660
44238
  return new WebAssembly.Instance(wasmModule, importObject);
43661
44239
  }
43662
- function loadJsUserFunctions(jsFiles, wasmFiles) {
44240
+ function loadJsUserFunctions(jsFiles, wasmFiles, nativeBridge2) {
43663
44241
  const result = /* @__PURE__ */ new Map();
43664
44242
  const wasmMap = wasmFiles ? buildWasmMap(wasmFiles) : /* @__PURE__ */ new Map();
43665
44243
  const wasmInstanceCache = /* @__PURE__ */ new Map();
@@ -43667,7 +44245,7 @@ function loadJsUserFunctions(jsFiles, wasmFiles) {
43667
44245
  const cached = wasmInstanceCache.get(name);
43668
44246
  if (cached) return cached;
43669
44247
  const data = wasmMap.get(name);
43670
- if (!data) return null;
44248
+ if (!data) return void 0;
43671
44249
  const instance = instantiateWasm(data);
43672
44250
  wasmInstanceCache.set(name, instance);
43673
44251
  return instance;
@@ -43685,8 +44263,18 @@ function loadJsUserFunctions(jsFiles, wasmFiles) {
43685
44263
  apply: branch.apply
43686
44264
  });
43687
44265
  };
43688
- const wasmName = parseWasmDirective(file.source) ?? funcName;
43689
- const wasmInstance = getWasmInstance(wasmName);
44266
+ const directives = parseDirectives(file.source);
44267
+ const wasmInstance = directives.wasm ? getWasmInstance(directives.wasm) : void 0;
44268
+ let nativeLib;
44269
+ if (directives.native && nativeBridge2) {
44270
+ const libFile = nativeLibFilename(directives.native);
44271
+ const dir = file.name.substring(0, file.name.lastIndexOf("/") + 1);
44272
+ const libPath = dir + libFile;
44273
+ try {
44274
+ nativeLib = nativeBridge2.load(libPath);
44275
+ } catch {
44276
+ }
44277
+ }
43690
44278
  const factory = new Function(
43691
44279
  "RTV",
43692
44280
  "RuntimeError",
@@ -43694,14 +44282,44 @@ function loadJsUserFunctions(jsFiles, wasmFiles) {
43694
44282
  "IType",
43695
44283
  "register",
43696
44284
  "wasm",
44285
+ "native",
43697
44286
  file.source
43698
44287
  );
43699
- factory(RTV, RuntimeError, FloatXArray, IType, registerFn, wasmInstance);
44288
+ factory(
44289
+ RTV,
44290
+ RuntimeError,
44291
+ FloatXArray,
44292
+ IType,
44293
+ registerFn,
44294
+ wasmInstance,
44295
+ nativeLib
44296
+ );
43700
44297
  if (branches.length === 0) {
43701
44298
  throw new Error(
43702
44299
  `JS user function '${funcName}' (${file.name}) must call register() at least once`
43703
44300
  );
43704
44301
  }
44302
+ if (directives.native || directives.wasm) {
44303
+ const parts = [];
44304
+ if (directives.native) {
44305
+ parts.push(nativeLib ? "native: loaded" : "native: not found");
44306
+ }
44307
+ if (directives.wasm) {
44308
+ parts.push(wasmInstance ? "wasm: loaded" : "wasm: not found");
44309
+ }
44310
+ const statusMsg = `${funcName}: ${parts.join(", ")}`;
44311
+ let logged = false;
44312
+ for (const branch of branches) {
44313
+ const origApply = branch.apply;
44314
+ branch.apply = (...applyArgs) => {
44315
+ if (!logged) {
44316
+ logged = true;
44317
+ console.log(statusMsg);
44318
+ }
44319
+ return origApply(...applyArgs);
44320
+ };
44321
+ }
44322
+ }
43705
44323
  result.set(funcName, branches);
43706
44324
  } catch (e) {
43707
44325
  const msg = e instanceof Error ? e.message : String(e);
@@ -43817,7 +44435,8 @@ function generateMainScriptCode(source, mainFileName = "script.m", workspaceFile
43817
44435
  _t0 = performance.now();
43818
44436
  const jsUserFunctions = loadJsUserFunctions(
43819
44437
  jsWorkspaceFiles,
43820
- wasmWorkspaceFiles
44438
+ wasmWorkspaceFiles,
44439
+ opts?.nativeBridge
43821
44440
  );
43822
44441
  const _loadJsUserFunctionsMs = performance.now() - _t0;
43823
44442
  _t0 = performance.now();
@@ -43959,7 +44578,7 @@ function generateMainScriptCode(source, mainFileName = "script.m", workspaceFile
43959
44578
  }
43960
44579
 
43961
44580
  // src/numbl-core/executeCode.ts
43962
- function executeCode(source, options = {}, workspaceFiles, mainFileName = "script.m", searchPaths) {
44581
+ function executeCode(source, options = {}, workspaceFiles, mainFileName = "script.m", searchPaths, nativeBridge2) {
43963
44582
  const initialVariableNames = options.initialVariableValues ? Object.keys(options.initialVariableValues) : void 0;
43964
44583
  const codegenStart = performance.now();
43965
44584
  const {
@@ -43983,7 +44602,7 @@ function executeCode(source, options = {}, workspaceFiles, mainFileName = "scrip
43983
44602
  workspaceFiles,
43984
44603
  initialVariableNames,
43985
44604
  searchPaths,
43986
- { noLineTracking: options.noLineTracking }
44605
+ { noLineTracking: options.noLineTracking, nativeBridge: nativeBridge2 }
43987
44606
  );
43988
44607
  const codegenTimeMs = performance.now() - codegenStart;
43989
44608
  if (options.log) {
@@ -44126,7 +44745,7 @@ function processMipLoad(packageName, _visited) {
44126
44745
  if (visited.has(packageName)) return [];
44127
44746
  visited.add(packageName);
44128
44747
  const mipDir = process.env.MIP_DIR || join3(homedir2(), ".mip");
44129
- const pkgDir = join3(mipDir, "packages", packageName);
44748
+ const pkgDir = join3(mipDir, "numbl_packages", packageName);
44130
44749
  const loadScript = join3(pkgDir, "load_package.m");
44131
44750
  if (!existsSync3(loadScript)) {
44132
44751
  throw new Error(
@@ -44140,7 +44759,7 @@ function processMipLoad(packageName, _visited) {
44140
44759
  const mipJson = JSON.parse(readFileSync3(mipJsonPath, "utf-8"));
44141
44760
  const deps = mipJson.dependencies ?? [];
44142
44761
  for (const dep of deps) {
44143
- const depPkgDir = join3(mipDir, "packages", dep);
44762
+ const depPkgDir = join3(mipDir, "numbl_packages", dep);
44144
44763
  if (!existsSync3(depPkgDir)) {
44145
44764
  console.warn(
44146
44765
  `Warning: dependency "${dep}" of "${packageName}" is not installed; skipping`
@@ -44380,7 +44999,7 @@ function saveHistoryEntry(entry, hist) {
44380
44999
  } catch {
44381
45000
  }
44382
45001
  }
44383
- async function runRepl(initialWorkspaceFiles, onDrawnow, initialSearchPaths) {
45002
+ async function runRepl(initialWorkspaceFiles, onDrawnow, initialSearchPaths, nativeBridge2) {
44384
45003
  let variableValues = {};
44385
45004
  let holdState = false;
44386
45005
  const workspaceFiles = [...initialWorkspaceFiles];
@@ -44439,7 +45058,8 @@ async function runRepl(initialWorkspaceFiles, onDrawnow, initialSearchPaths) {
44439
45058
  },
44440
45059
  workspaceFiles,
44441
45060
  "repl",
44442
- searchPaths
45061
+ searchPaths,
45062
+ nativeBridge2
44443
45063
  );
44444
45064
  variableValues = result.variableValues;
44445
45065
  holdState = result.holdState;
@@ -44547,7 +45167,8 @@ async function runRepl(initialWorkspaceFiles, onDrawnow, initialSearchPaths) {
44547
45167
  },
44548
45168
  workspaceFiles,
44549
45169
  "repl",
44550
- searchPaths
45170
+ searchPaths,
45171
+ nativeBridge2
44551
45172
  );
44552
45173
  variableValues = result.variableValues;
44553
45174
  holdState = result.holdState;
@@ -44989,15 +45610,27 @@ try {
44989
45610
  nativeAddonLoaded = true;
44990
45611
  } catch {
44991
45612
  }
45613
+ var nativeBridge;
45614
+ try {
45615
+ const req = createRequire(import.meta.url);
45616
+ const koffi = req("koffi");
45617
+ nativeBridge = { load: (path) => koffi.load(path) };
45618
+ } catch {
45619
+ }
44992
45620
  function scanMFiles(dirPath, excludeFile) {
44993
45621
  const files = [];
45622
+ let entries;
44994
45623
  try {
44995
- const entries = readdirSync2(dirPath);
44996
- for (const entry of entries) {
44997
- const fullPath = join6(dirPath, entry);
44998
- if (excludeFile && fullPath === excludeFile) {
44999
- continue;
45000
- }
45624
+ entries = readdirSync2(dirPath);
45625
+ } catch {
45626
+ return files;
45627
+ }
45628
+ for (const entry of entries) {
45629
+ const fullPath = join6(dirPath, entry);
45630
+ if (excludeFile && fullPath === excludeFile) {
45631
+ continue;
45632
+ }
45633
+ try {
45001
45634
  const stat = statSync2(fullPath);
45002
45635
  if (stat.isDirectory()) {
45003
45636
  if (entry.startsWith("@") || entry.startsWith("+") || entry === "private") {
@@ -45017,8 +45650,11 @@ function scanMFiles(dirPath, excludeFile) {
45017
45650
  data: new Uint8Array(data)
45018
45651
  });
45019
45652
  }
45653
+ } catch (err) {
45654
+ console.warn(
45655
+ `Warning: could not read ${fullPath}: ${err instanceof Error ? err.message : String(err)}`
45656
+ );
45020
45657
  }
45021
- } catch {
45022
45658
  }
45023
45659
  return files;
45024
45660
  }
@@ -45078,7 +45714,8 @@ async function runTests(dir) {
45078
45714
  { displayResults: true },
45079
45715
  workspaceFiles,
45080
45716
  mainFileName,
45081
- searchPaths
45717
+ searchPaths,
45718
+ nativeBridge
45082
45719
  );
45083
45720
  const outputText = result.output.join("");
45084
45721
  const lines = outputText.split("\n").filter((l) => l.length > 0);
@@ -45377,7 +46014,8 @@ async function executeWithOptions(code, mainFileName, workspaceFiles, opts, sear
45377
46014
  },
45378
46015
  workspaceFiles,
45379
46016
  mainFileName,
45380
- searchPaths
46017
+ searchPaths,
46018
+ nativeBridge
45381
46019
  );
45382
46020
  if (result.plotInstructions.length > 0) {
45383
46021
  streamLine({
@@ -45425,7 +46063,8 @@ async function executeWithOptions(code, mainFileName, workspaceFiles, opts, sear
45425
46063
  },
45426
46064
  workspaceFiles,
45427
46065
  mainFileName,
45428
- searchPaths
46066
+ searchPaths,
46067
+ nativeBridge
45429
46068
  );
45430
46069
  writeProfileIfNeeded(result);
45431
46070
  if (opts.dumpJs) {
@@ -45453,7 +46092,8 @@ async function executeWithOptions(code, mainFileName, workspaceFiles, opts, sear
45453
46092
  },
45454
46093
  workspaceFiles,
45455
46094
  mainFileName,
45456
- searchPaths
46095
+ searchPaths,
46096
+ nativeBridge
45457
46097
  );
45458
46098
  writeProfileIfNeeded(result);
45459
46099
  if (opts.dumpJs) {
@@ -45538,7 +46178,7 @@ async function cmdRepl(args) {
45538
46178
  !opts.plot,
45539
46179
  replPlotOpts
45540
46180
  );
45541
- await runRepl(replFiles, replDrawnow, replSearchPaths);
46181
+ await runRepl(replFiles, replDrawnow, replSearchPaths, nativeBridge);
45542
46182
  }
45543
46183
  function createPlotHandler(disabled, plotOpts) {
45544
46184
  if (disabled) {